Python存取XML方法簡介


目前而言,Python 3.2存取XML有以下四種方法:
  1.Expat
  2.DOM
  3.SAX
  4.ElementTree

以以下xml作為討論依據

<?xml version="1.0" encoding="utf-8"?>
<Schools>
    <School Name="XiDian">
        <Class Id="030612">
            <Student Name="salomon">
                <Scores>
                    <Math>98</Math>
                    <English>85</English>
                    <physics>89</physics>
                </Scores>
            </Student>
            <Student Name="Jupiter">
                <Scores>
                    <Math>74</Math>
                    <English>83</English>
                    <physics>69</physics>
                </Scores>
            </Student>
        </Class>
        <Class Id="030611">
            <Student Name="Venus">
                <Scores>
                    <Math>98</Math>
                    <English>85</English>
                    <physics>89</physics>
                </Scores>
            </Student>
            <Student Name="Mars">
                <Scores>
                    <Math>74</Math>
                    <English>83</English>
                    <physics>69</physics>
                </Scores>
            </Student>
        </Class>
    </School>
</Schools>

 

Expat

  Expat是一個面向流的解析器。您注冊的解析器回調(或handler)功能,然后開始搜索它的文檔。當解析器識別該文件的指定的位置,它會調用該部分相應的處理程序(如果您已經注冊的一個)。該文件被輸送到解析器,會被分割成多個片斷,並分段裝到內存中。因此expat可以解析那些巨大的文件。

SAX

  SAX是個循序存取XML的解析器API,一個實現SAX的解析器(也就是“SAX Parser”)以一個串流解析器的型式作用,擁有事件驅動API。由使用者定義回調函數,解析時,若發生事件的話會被調用。事件在任一XML特性遇到時引發,以及遇到他們結尾時再次引發。XML屬性也作為傳給元素事件資料的一部分。SAX 處理時單方向性的;解析過的資料無法在不重新開始的情況下再次讀取。

DOM

  DOM解析器在任何處理開始之前,必須把整棵樹放在內存,所以DOM解析器的內存使用量完全根據輸入資料的大小(相對來說,SAX解析器的內存內容,是只基於XML檔案的最大深度(XML樹的最大深度)和單一XML項目上XML屬性儲存的最大資料)。

     DOM在python3.2中有兩種實現方式:
    1.xml.minidom是一個基本的實現。
    2.xml.pulldom只在需要時構建被訪問的子樹。

'''
Created on 2012-5-25

@author: salomon
'''

import xml.dom.minidom as minidom


dom = minidom.parse("E:\\test.xml")
root = dom.getElementsByTagName("Schools") #The function getElementsByTagName returns NodeList.
print(root.length)

for node in root: 
    print("Root element is %s。" %node.tagName)# 格式化輸出,與C系列語言有很大區別。
    schools = node.getElementsByTagName("School")
    for school in schools:
        print(school.nodeName)
        print(school.tagName)
        print(school.getAttribute("Name"))
        print(school.attributes["Name"].value)
        classes = school.getElementsByTagName("Class")
        print("There are %d classes in school %s" %(classes.length, school.getAttribute("Name")))
        for mclass in classes:
            print(mclass.getAttribute("Id"))
            for student in mclass.getElementsByTagName("Student"):
                print(student.attributes["Name"].value)
                print(student.getElementsByTagName("English")[0].nodeValue) #這個為什么啊?
                print(student.getElementsByTagName("English")[0].childNodes[0].nodeValue)
                student.getElementsByTagName("English")[0].childNodes[0].nodeValue = 75

f =  open('new.xml',  'w', encoding = 'utf-8')
dom.writexml(f,encoding = 'utf-8')
f.close()                  

 

ElementTree

      目前搜到的ElementTree的信息較少,目前不知道其工作機制。有資料顯示ElementTree近乎一種輕量級的DOM,但是ElementTree 所有的 Element 節點的工作方式是一致的。它很類似於C#中的XpathNavigator。

'''
Created on 2012-5-25

@author: salomon
'''
from xml.etree.ElementTree import ElementTree

tree = ElementTree()
tree.parse("E:\\test.xml")
root = tree.getroot()
print(root.tag)
print(root[0].tag)
print(root[0].attrib)
schools = root.getchildren() 
for school in schools:
    print(school.get("Name"))
    classes = school.findall("Class")
    for mclass in classes:
        print(mclass.items())
        print(mclass.keys())
        print(mclass.attrib["Id"])
        math = mclass.find("Student").find("Scores").find("Math")
        print(math.text)
        math.set("teacher", "bada")
        
tree.write("new.xml")

 

 

Compare:

       就以上幾點來說Expat和SAX解析XML方式相同,就是不知道性能相比怎樣。DOM相對於以上兩種解析器,消耗內存,而且由於存取耗時,所以處理文件相對來說慢。如果文件太大無法載入內存,DOM這種解析器就不能用了,但是對於,某些種類的XML驗證需要存取整份文件,或者某些XML處理僅要求存取整份文件的需求時,DOM是唯一選擇。

Note:

       需要指出的是存取XML的這幾項技術並不是Python獨創的,Python也是通過借鑒其他語言或者直接從其他語言引入進來的。例如Expat就是一個用C語言開發的、用來解析XML文檔的開發庫。而SAX最初是由DavidMegginson采用java語言開發的,DOM可以以一種獨立於平台和語言的方式訪問和修改一個文檔的內容和結構。可以應用於任何編程語言。

 

做為對比我也想列舉一下C#存取XML文檔的方式:

  1. 基於DOM的XmlDocument

  2. 基於流文件的XmlReader 和 XmlWriter(它和SAX流文件實現不同,SAX是事件驅動模型)。

  3. Linq to Xml

 流文件兩種模型:XmlReader/XMLWriter VS SAX

      流模型每次迭代XML文檔中的一個節點,適合於處理較大的文檔,所耗內存空間小。流模型中有兩種變體——“推”模型和“拉”模型。
  推模型也就是常說的SAX,SAX是一種靠事件驅動的模型,也就是說:它每發現一個節點就用推模型引發一個事件,而我們必須編寫這些事件的處理程序,這樣的做法非常的不靈活,也很麻煩。
  .NET中使用的是基於“拉”模型的實現方案,“拉”模型在遍歷文檔時會把感興趣的文檔部分從讀取器中拉出,不需要引發事件,允許我們以編程的方式訪問文檔,這大大的提高了靈活性,在性能上“拉”模型可以選擇性的處理節點,而SAX每發現一個節點都會通知客戶機,從而,使用“拉”模型可以提高Application的整體效率。

 

 

Reference:

http://docs.python.org/py3k/

http://blog.csdn.net/kbkiss2010/article/details/5783834


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM