2010-02-11 182 views
1

這可能是一個新手問題:)但是由於我不熟悉XML,所以它令我感到惱火。我有以下XML文件:獲取特定的xml節點屬性

<assetsMain> 
    <assetParent type='character' shortName='char'> 
    <asset> 
     pub 
    </asset> 
    <asset> 
     car 
    </asset> 
    </assetParent> 
    <assetParent type='par' shortName='pr'> 
    <asset> 
     camera 
    </asset> 
    <asset> 
     rig 
    </asset> 
    </assetParent> 
</assetsMain> 

是否可以檢索所有<assetParent>節點及其所有屬性和孩子的文本?例如有結果如下:

[ [['character','char'],['pub','car']] 
    [['par','pr'],['camera','rig']] 
] 

順便說一句,我使用DOM和Python 2.6

在此先感謝。

+0

我不會自己打敗了。 XML不能很好地映射到常見的編程數據類型。處理它可能是一個完整的痛苦。 XPATH是一種有效而強大的訪問XML數據的方法,可能很難掌握。我很難找到有用的例子。 – MattH 2010-02-11 13:59:35

回答

3

使用lxml.etree的答案。 Xpath的很可能是可重複使用的另一種能夠庫:

>>> from lxml import etree 
>>> data = """<assetsMain> 
... <assetParent type='character' shortName='char'> 
... <asset>pub</asset> 
... <asset>car</asset> 
... </assetParent> 
... <assetParent type='par' shortName='pr'> 
... <asset>camera</asset> 
... <asset>rig</asset> 
... </assetParent> 
... </assetsMain> 
... """ 
>>> doc = etree.XML(data) 
>>> for aP in doc.xpath('//assetParent'): 
... parent = aP.attrib['type'] 
... for a in aP.xpath('./asset/text()'): 
...  print parent, a.strip() 
... 
character pub 
character car 
par camera 
par rig 
0

此代碼給你想要的輸出:

from xml.dom.minidom import parseString 

document = """\ 
<assetsMain> 
    <assetParent type='character' shortName='char'> 
    <asset> 
     pub 
    </asset> 
    <asset> 
     car 
    </asset> 
    </assetParent> 
    <assetParent type='par' shortName='pr'> 
    <asset> 
     camera 
    </asset> 
    <asset> 
     rig 
    </asset> 
    </assetParent> 
</assetsMain> 
""" 

def getNestedList(): 
    dom = parseString(document) 
    li = [] 
    for assetParent in dom.childNodes[0].getElementsByTagName("assetParent"): 
     # read type and shortName 
     a = [assetParent.getAttribute("type"), assetParent.getAttribute("shortName")] 
     # read content of asset nodes 
     b = [asset.childNodes[0].data.strip() for asset in assetParent.getElementsByTagName("asset")] 
     # put the lists together in a list and add them to the list (!) 
     li.append([a,b]) 
    return li 

if __name__=="__main__": 
    print getNestedList() 

請注意,我們可以選擇我們想要與getElementsByTagName讀哪些子節點。在節點上用getAttribute讀取屬性。節點內的文本內容通過屬性data讀取(文本本身也是一個子節點)。如果你正在讀一個節點內的文本,您可以檢查,使其真正與文本:

if node.nodeType == node.TEXT_NODE: 

另外請注意,沒有檢查或錯誤處理在這裏。缺少子節點的節點將引發IndexError

雖然,三個級別的嵌套列表讓我想建議您使用字典,而不是。

輸出:

[[[u'character', u'char'], [u'pub', u'car']], [[u'par', u'pr'], [u'camera', u'rig']]]