<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                xml在軟件領域用途非常廣泛,有名人曰: > “當 XML(擴展標記語言)于 1998 年 2 月被引入軟件工業界時,它給整個行業帶來了一場風暴。有史以來第一次,這個世界擁有了一種用來結構化文檔和數據的通用且適應性強的格式,它不僅僅可以用于 WEB,而且可以被用于任何地方。” > > ---《Designing With Web Standards Second Edition》, Jeffrey Zeldman 對于xml如果要做一個定義式的說明,就不得不引用w3school里面簡潔而明快的說明: * XML 指可擴展標記語言(EXtensible Markup Language) * XML 是一種標記語言,很類似 HTML * XML 的設計宗旨是傳輸數據,而非顯示數據 * XML 標簽沒有被預定義。您需要自行定義標簽。 * XML 被設計為具有自我描述性。 * XML 是 W3C 的推薦標準 如果讀者要詳細了解和學習有關xml,可以閱讀[w3school的教程](http://www.w3school.com.cn/xml/xml_intro.asp) xml的重要,關鍵在于它是用來傳輸數據,因為傳輸數據,特別是在web編程中,經常要用到的。有了這樣一種東西,就讓數據傳輸變得簡單了。對于這么重要的,python當然有支持。 一般來講,一個引人關注的東西,總會有很多人從不同側面去關注。在編程語言中也是如此,所以,對xml這個明星式的東西,python提供了多種模塊來處理。 * xml.dom.* 模塊:Document Object Model。適合用于處理 DOM API。它能夠將xml數據在內存中解析成一個樹,然后通過對樹的操作來操作xml。但是,這種方式由于將xml數據映射到內存中的樹,導致比較慢,且消耗更多內存。 * xml.sax.* 模塊:simple API for XML。由于SAX以流式讀取xml文件,從而速度較快,切少占用內存,但是操作上稍復雜,需要用戶實現回調函數。 * xml.parser.expat:是一個直接的,低級一點的基于 C 的 expat 的語法分析器。 expat接口基于事件反饋,有點像 SAX 但又不太像,因為它的接口并不是完全規范于 expat 庫的。 * xml.etree.ElementTree (以下簡稱 ET):元素樹。它提供了輕量級的python式的API,相對于DOM,ET快了很多 ,而且有很多令人愉悅的API可以使用;相對于SAX,ET也有ET.iterparse提供了 “在空中” 的處理方式,沒有必要加載整個文檔到內存,節省內存。ET的性能的平均值和SAX差不多,但是API的效率更高一點而且使用起來很方便。 所以,我用xml.etree.ElementTree ElementTree在標準庫中有兩種實現。一種是純Python實現:xml.etree.ElementTree ,另外一種是速度快一點:xml.etree.cElementTree 。 如果讀者使用的是python2.x,可以像這樣引入模塊: ~~~ try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET ~~~ 如果是Python3.3以上,就沒有這個必要了,只需要一句話`import xml.etree.ElementTree as ET`即可,然后由模塊自動來尋找適合的方式。顯然python3.x相對python2.x有了很大進步。但是,本教程礙于很多工程項目還沒有升級換代,暫且忍受了。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/226.md#遍歷查詢)遍歷查詢 先要搞一個xml文檔。為了圖省事,我就用w3school中的一個例子: [![](https://box.kancloud.cn/2015-09-07_55ed50cfe455a.jpg)](https://github.com/qiwsir/StarterLearningPython/blob/master/2images/22601.jpg) 這是一個xml樹,只不過是用圖來表示的,還沒有用ET解析呢。把這棵樹寫成xml文檔格式: ~~~ <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore> ~~~ 將xml保存為名為22601.xml的文件,然后對其進行如下操作: ~~~ >>> import xml.etree.cElementTree as ET ~~~ 為了簡化,我用這種方式引入,如果在編程實踐中,推薦讀者使用try...except...方式。 ~~~ >>> tree = ET.ElementTree(file="22601.xml") >>> tree <ElementTree object at 0xb724cc2c> ~~~ 建立起xml解析樹。然后可以通過根節點向下開始讀取各個元素(element對象)。 在上述xml文檔中,根元素是,它沒有屬性,或者屬性為空。 ~~~ >>> root = tree.getroot() #獲得根 >>> root.tag 'bookstore' >>> root.attrib {} ~~~ 要想將根下面的元素都讀出來,可以: ~~~ >>> for child in root: ... print child.tag, child.attrib ... book {'category': 'COOKING'} book {'category': 'CHILDREN'} book {'category': 'WEB'} ~~~ 也可以這樣讀取指定元素的信息: ~~~ >>> root[0].tag 'book' >>> root[0].attrib {'category': 'COOKING'} >>> root[0].text #無內容 '\n ' ~~~ 再深點,就有感覺了: ~~~ >>> root[0][0].tag 'title' >>> root[0][0].attrib {'lang': 'en'} >>> root[0][0].text 'Everyday Italian' ~~~ 對于ElementTree對象,有一個iter方法可以對指定名稱的子節點進行深度優先遍歷。例如: ~~~ >>> for ele in tree.iter(tag="book"): #遍歷名稱為book的節點 ... print ele.tag, ele.attrib ... book {'category': 'COOKING'} book {'category': 'CHILDREN'} book {'category': 'WEB'} >>> for ele in tree.iter(tag="title"): #遍歷名稱為title的節點 ... print ele.tag, ele.attrib, ele.text ... title {'lang': 'en'} Everyday Italian title {'lang': 'en'} Harry Potter title {'lang': 'en'} Learning XML ~~~ 如果不指定元素名稱,就是將所有的元素遍歷一邊。 ~~~ >>> for ele in tree.iter(): ... print ele.tag, ele.attrib ... bookstore {} book {'category': 'COOKING'} title {'lang': 'en'} author {} year {} price {} book {'category': 'CHILDREN'} title {'lang': 'en'} author {} year {} price {} book {'category': 'WEB'} title {'lang': 'en'} author {} year {} price {} ~~~ 除了上面的方法,還可以通過路徑,搜索到指定的元素,讀取其內容。這就是xpath。此處對xpath不詳解,如果要了解可以到網上搜索有關信息。 ~~~ >>> for ele in tree.iterfind("book/title"): ... print ele.text ... Everyday Italian Harry Potter Learning XML ~~~ 利用findall()方法,也可以是實現查找功能: ~~~ >>> for ele in tree.findall("book"): ... title = ele.find('title').text ... price = ele.find('price').text ... lang = ele.find('title').attrib ... print title, price, lang ... Everyday Italian 30.00 {'lang': 'en'} Harry Potter 29.99 {'lang': 'en'} Learning XML 39.95 {'lang': 'en'} ~~~ ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/226.md#編輯)編輯 除了讀取有關數據之外,還能對xml進行編輯,即增刪改查功能。還是以上面的xml文檔為例: ~~~ >>> root[1].tag 'book' >>> del root[1] >>> for ele in root: ... print ele.tag ... book book ~~~ 如此,成功刪除了一個節點。原來有三個book節點,現在就還剩兩個了。打開源文件再看看,是不是正好少了第二個節點呢?一定很讓你失望,源文件居然沒有變化。 的確如此,源文件沒有變化,這就對了。因為至此的修改動作,還是停留在內存中,還沒有將修改結果輸出到文件。不要忘記,我們是在內存中建立的ElementTree對象。再這樣做: ~~~ >>> import os >>> outpath = os.getcwd() >>> file = outpath + "/22601.xml" ~~~ 把當前文件路徑拼裝好。然后: ~~~ >>> tree.write(file) ~~~ 再看源文件,已經變成兩個節點了。 除了刪除,也能夠修改: ~~~ >>> for price in root.iter("price"): #原來每本書的價格 ... print price.text ... 30.00 39.95 >>> for price in root.iter("price"): #每本上漲7元,并且增加屬性標記 ... new_price = float(price.text) + 7 ... price.text = str(new_price) ... price.set("updated","up") ... >>> tree.write(file) ~~~ 查看源文件: ~~~ <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price updated="up">37.0</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price updated="up">46.95</price> </book> </bookstore> ~~~ 不僅價格修改了,而且在price標簽里面增加了屬性標記。干得不錯。 上面用`del`來刪除某個元素,其實,在編程中,這個用的不多,更喜歡用remove()方法。比如我要刪除`price > 40`的書。可以這么做: ~~~ >>> for book in root.findall("book"): ... price = book.find("price").text ... if float(price) > 40.0: ... root.remove(book) ... >>> tree.write(file) ~~~ 于是就這樣了: ~~~ <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price updated="up">37.0</price> </book> </bookstore> ~~~ 接下來就要增加元素了。 ~~~ >>> import xml.etree.cElementTree as ET >>> tree = ET.ElementTree(file="22601.xml") >>> root = tree.getroot() >>> ET.SubElement(root, "book") #在root里面添加book節點 <Element 'book' at 0xb71c7578> >>> for ele in root: ... print ele.tag ... book book >>> b2 = root[1] #得到新增的book節點 >>> b2.text = "python" #添加內容 >>> tree.write("22601.xml") ~~~ 查看源文件: ~~~ <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price updated="up">37.0</price> </book> <book>python</book> </bookstore> ~~~ ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/226.md#常用屬性和方法總結)常用屬性和方法總結 ET里面的屬性和方法不少,這里列出常用的,供使用中備查。 **Element對象** 常用屬性: * tag:string,元素數據種類 * text:string,元素的內容 * attrib:dictionary,元素的屬性字典 * tail:string,元素的尾形 針對屬性的操作 * clear():清空元素的后代、屬性、text和tail也設置為None * get(key, default=None):獲取key對應的屬性值,如該屬性不存在則返回default值 * items():根據屬性字典返回一個列表,列表元素為(key, value) * keys():返回包含所有元素屬性鍵的列表 * set(key, value):設置新的屬性鍵與值 針對后代的操作 * append(subelement):添加直系子元素 * extend(subelements):增加一串元素對象作為子元素 * find(match):尋找第一個匹配子元素,匹配對象可以為tag或path * findall(match):尋找所有匹配子元素,匹配對象可以為tag或path * findtext(match):尋找第一個匹配子元素,返回其text值。匹配對象可以為tag或path * insert(index, element):在指定位置插入子元素 * iter(tag=None):生成遍歷當前元素所有后代或者給定tag的后代的迭代器 * iterfind(match):根據tag或path查找所有的后代 * itertext():遍歷所有后代并返回text值 * remove(subelement):刪除子元素 **ElementTree對象** * find(match) * findall(match) * findtext(match, default=None) * getroot():獲取根節點. * iter(tag=None) * iterfind(match) * parse(source, parser=None):裝載xml對象,source可以為文件名或文件類型對象. * write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None,method="xml")  ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/226.md#一個實例)一個實例 最后,提供一個參考,這是一篇來自網絡的文章:[Python xml屬性、節點、文本的增刪改](http://blog.csdn.net/wklken/article/details/7603071),本文的源碼我也復制到下面,請讀者參考: > 實現思想: > > 使用ElementTree,先將文件讀入,解析成樹,之后,根據路徑,可以定位到樹的每個節點,再對節點進行修改,最后直接將其輸出. ~~~ #!/usr/bin/python # -*- coding=utf-8 -*- # author : wklken@yeah.net # date: 2012-05-25 # version: 0.1 from xml.etree.ElementTree import ElementTree,Element def read_xml(in_path): ''' 讀取并解析xml文件 in_path: xml路徑 return: ElementTree ''' tree = ElementTree() tree.parse(in_path) return tree def write_xml(tree, out_path): ''' 將xml文件寫出 tree: xml樹 out_path: 寫出路徑 ''' tree.write(out_path, encoding="utf-8",xml_declaration=True) def if_match(node, kv_map): ''' 判斷某個節點是否包含所有傳入參數屬性 node: 節點 kv_map: 屬性及屬性值組成的map ''' for key in kv_map: if node.get(key) != kv_map.get(key): return False return True #---------------search ----- def find_nodes(tree, path): ''' 查找某個路徑匹配的所有節點 tree: xml樹 path: 節點路徑 ''' return tree.findall(path) def get_node_by_keyvalue(nodelist, kv_map): ''' 根據屬性及屬性值定位符合的節點,返回節點 nodelist: 節點列表 kv_map: 匹配屬性及屬性值map ''' result_nodes = [] for node in nodelist: if if_match(node, kv_map): result_nodes.append(node) return result_nodes #---------------change ----- def change_node_properties(nodelist, kv_map, is_delete=False): ''' 修改/增加 /刪除 節點的屬性及屬性值 nodelist: 節點列表 kv_map:屬性及屬性值map ''' for node in nodelist: for key in kv_map: if is_delete: if key in node.attrib: del node.attrib[key] else: node.set(key, kv_map.get(key)) def change_node_text(nodelist, text, is_add=False, is_delete=False): ''' 改變/增加/刪除一個節點的文本 nodelist:節點列表 text : 更新后的文本 ''' for node in nodelist: if is_add: node.text += text elif is_delete: node.text = "" else: node.text = text def create_node(tag, property_map, content): ''' 新造一個節點 tag:節點標簽 property_map:屬性及屬性值map content: 節點閉合標簽里的文本內容 return 新節點 ''' element = Element(tag, property_map) element.text = content return element def add_child_node(nodelist, element): ''' 給一個節點添加子節點 nodelist: 節點列表 element: 子節點 ''' for node in nodelist: node.append(element) def del_node_by_tagkeyvalue(nodelist, tag, kv_map): ''' 同過屬性及屬性值定位一個節點,并刪除之 nodelist: 父節點列表 tag:子節點標簽 kv_map: 屬性及屬性值列表 ''' for parent_node in nodelist: children = parent_node.getchildren() for child in children: if child.tag == tag and if_match(child, kv_map): parent_node.remove(child) if __name__ == "__main__": #1\. 讀取xml文件 tree = read_xml("./test.xml") #2\. 屬性修改 #A. 找到父節點 nodes = find_nodes(tree, "processers/processer") #B. 通過屬性準確定位子節點 result_nodes = get_node_by_keyvalue(nodes, {"name":"BProcesser"}) #C. 修改節點屬性 change_node_properties(result_nodes, {"age": "1"}) #D. 刪除節點屬性 change_node_properties(result_nodes, {"value":""}, True) #3\. 節點修改 #A.新建節點 a = create_node("person", {"age":"15","money":"200000"}, "this is the firest content") #B.插入到父節點之下 add_child_node(result_nodes, a) #4\. 刪除節點 #定位父節點 del_parent_nodes = find_nodes(tree, "processers/services/service") #準確定位子節點并刪除之 target_del_node = del_node_by_tagkeyvalue(del_parent_nodes, "chain", {"sequency" : "chain1"}) #5\. 修改節點文本 #定位節點 text_nodes = get_node_by_keyvalue(find_nodes(tree, "processers/services/service/chain"), {"sequency":"chain3"}) change_node_text(text_nodes, "new text") #6\. 輸出到結果文件 write_xml(tree, "./out.xml") ~~~ 操作對象(原始xml文件): ~~~ <?xml version="1.0" encoding="UTF-8"?> <framework> <processers> <processer name="AProcesser" file="lib64/A.so" path="/tmp"> </processer> <processer name="BProcesser" file="lib64/B.so" value="fordelete"> </processer> <processer name="BProcesser" file="lib64/B.so2222222"/> <services> <service name="search" prefix="/bin/search?" output_formatter="OutPutFormatter:service_inc"> <chain sequency="chain1"/> <chain sequency="chain2"></chain> </service> <service name="update" prefix="/bin/update?"> <chain sequency="chain3" value="fordelete"/> </service> </services> </processers> </framework> ~~~ 執行程序之后,得到的結果文件: ~~~ <?xml version='1.0' encoding='utf-8'?> <framework> <processers> <processer file="lib64/A.so" name="AProcesser" path="/tmp"> </processer> <processer age="1" file="lib64/B.so" name="BProcesser"> <person age="15" money="200000">this is the firest content</person> </processer> <processer age="1" file="lib64/B.so2222222" name="BProcesser"> <person age="15" money="200000">this is the firest content</person> </processer> <services> <service name="search" output_formatter="OutPutFormatter:service_inc" prefix="/bin/search?"> <chain sequency="chain2" /> </service> <service name="update" prefix="/bin/update?"> <chain sequency="chain3" value="fordelete">new text</chain> </service> </services> </processers> </framework> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看