获取特定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
这段代码会输出你想要的结果:
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']]]
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