http://zc0604.iteye.com/blog/1520703
http://www.cnblogs.com/rirtue/archive/2012/01/12/2321028.html
http://blog.csdn.net/zgx007/article/details/6107226
1,xml的文檔結構 1.1,XML文檔包括XML頭資訊和XML資訊體 1.1.1,XML文檔頭資訊
<?xml version="1.0" encoding="utf-8"?>
它表明了此XML文檔所用的版本,編碼方式。有些複雜的還有一些文件類型的定義(DOCTYPE),用於定義此XML文檔所用的DTD或Schema和一些實體的定義。
1.1.2,XML文檔資訊體
<Table><Name>tbl_test</Name><Comment>This ia a test table</Comment><Schema format="Json"> </Schema></Table>
XML資訊體是由樹狀元素組成。每個XML文檔都有一個文件項目,也就是樹的根項目,所有其它的元素和內容都包含在根項目中。
DOM是Document Object Model的簡稱,它是以對象樹來表示一個XML文檔的方法,使用它的好處就是你可以非常靈活的在對象中進行遍曆。
2,minidom模組讀取XML
按照我的理解,在獲得XML文檔樹的根節點後,實際上分為兩種節點【這裡測試只用到這兩種節點,實際按照nodeType知道還有其他很多】:元素節點(ELEMENT NODE)和文本節點(TEXT NODE)。元素節點如上面的Name標籤,整個就是一個元素節點。文本節點如上面的tbl_test,也作為一個節點,即文本節點。
節點都具有這樣三種屬性;
node.nodeName |
nodeName為結點名字 |
node.nodeValue |
nodeValue是結點的值,只對文本結點有效 |
node.nodeType |
nodeType是結點的類型 |
元素節點(ELEMENT NODE)可以用root.getElementsByTagName("Table")這樣來擷取以Table標籤的一個列表。
文本節點(TEXT NODE) 可以用column.getAttribute('Name')這樣來擷取Name的這樣一個屬性值。屬性指的是: <Column Name="pt" Value="1"/>這樣的結構。可以使用node.data或者node.nodeValue來擷取文本值。 2.1,得到dom對象
從xml檔案得到dom對象
>>> import xml.dom.minidom>>> dom = xml.dom.minidom.parse('d:/catalog.xml')
從xml字串得到dom對象
>>> import xml.dom.minidom>>> dom = xml.dom.minidom.parseString(xmlstring)
2.2,得到文件項目對象
>>> root = dom.documentElement
3,測試
3.1,實驗1
<?xml version="1.0" encoding="UTF-8"?><Table><Name>tbl_test</Name><Comment>This ia a test table</Comment><Schema format="Json"> </Schema></Table>
dom = parseString(string1)#root = dom.documentElementtable = dom.getElementsByTagName( "Table" )[0]name = table.getElementsByTagName( "Name" )[0]for textNode in name.childNodes: print textNode.data print textNode.nodeValue
1,dom獲得的是整個xml對象
2,【未運行】root獲得的整個文檔對象,如果執行了,實際上得到的是根節點唯一的標籤<Table></Table>下的東西,如果有多個<Table></Table>,估計會忽略,預設把第一個當成根。
3,root.getElementsByTagName( "Table" )將獲得所有<Table></Table>標籤對,這是一個類似於列表的東西,可以用列表方法擷取。因為這裡就一個<Table></Table>標籤,所以直接[0]返回這個單獨的對象。
4,table獲得的是真正的單個的其中的<table></Table>對象。
5,table.getElementsByTagName( "Name" )同樣獲得的是一個[<Name></Name>,...,<Name></Name>]這樣的列表。
6,name獲得的是單個的現在僅有的<Name></Name>對象。
7,由於name下面是文本節點tbl_test。雖然只有一個,但可以有多個。此時,前述的都是元素節點,Name標籤下都是文本節點了,可以用name.childNodes獲得文本節點列表,注意,還是列表。
8,textNode是其中的唯一的一個tbl_test。
9,因為是文本節點,所有有data屬性。當然其,node.nodeValue也可以讀到。
3.2,實驗2
<?xml version="1.0" encoding="UTF-8"?><Partitions><Partition><Column Name="pt" Value="1"/></Partition></Partitions>
dom = parseString(string2)#root = dom.documentElementpartitions = dom.getElementsByTagName("Partitions")[0]partition = partitions.getElementsByTagName("Partition")[0]column = partition.getElementsByTagName("Column")[0]print column.getAttribute('Name')
1,dom獲得的是整個xml對象
2,【未運行】root獲得的整個文檔對象,如果執行了,實際上得到的是根節點唯一的標籤<Table></Table>下的東西,如果有多個<Partitions></Partitions>,估計會忽略,預設把第一個當成根。
3,root.getElementsByTagName( "Partitions" )將獲得所有<Partitions></Partitions>標籤對,這是一個類似於列表的東西,可以用列表方法擷取。因為這裡就一個<Partitions></Partitions>標籤,所以直接[0]返回這個單獨的對象。
4,partitions獲得的是真正的單個的其中的<Partitions></Partitions>對象。
5,partitions.getElementsByTagName( "Partition" )同樣獲得的是一個[<Partition></Partition>,...,<Partition></Partition>]這樣的列表。
6,partition獲得的是單個的現在僅有的<Partition></Partition>對象。
7,column以同樣方式擷取到單個的<Column></Column>對象
8,由於Name是Column的一個屬性,所以用column.getAttribute('Name')來擷取這個屬性值
3.3,實驗3
string1='''<?xml version="1.0" encoding="UTF-8"?> <Table> <Name> tbl_test </Name> <Comment> <Name> gexing </Name> This ia a test table </Comment> <Schema format="Json"> </Schema> <Name> dandan </Name> </Table> '''
dom = parseString(string1) root = dom.documentElement names = root.getElementsByTagName("Name") for name in names: for child in name.childNodes: print child.nodeValue
輸出:
[admin@r42h06016.xy2.aliyun.com]$python test.py tbl_test gexing dandan
注意點1,空行是因為實際上要的xml是無空格的內容。
注意點2,說明用getElementsByTagName得到的list是遍曆所有“節點”,然後不管哪個層次,遇到一個符合的就會加進來。如果沒有文本資訊,就輸出None。
3.4,簡單函數
對於簡單的元素,如:<caption>Python</caption>,我們可以編寫這樣一個函數來得到它的內容(這裡為Python)。
def getTagText(root, tag): node = root.getElementsByTagName(tag)[0] rc = "" for node in node.childNodes: if node.nodeType in ( node.TEXT_NODE, node.CDATA_SECTION_NODE): rc = rc + node.data return rc
4,xml.etree.ElementTree模組讀xml
import xml.etree.ElementTreecontent = xml.etree.ElementTree.fromstring(string1)name = content.findall('Name')#找到所有的Name的列表name = content.findtext('Name')#找到下一層的Name節點