获取特定的xml节点属性

时间:2010-02-11 13:17:10

标签: python 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

提前致谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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']]]