Sty*_*ize 5 python xml xpath lxml
我正在玩一个 xml 文件@ http://www.jsphylosvg.com/examples/source.php?example=2&t=xml
如果 node 的值,我想插入一个节点name="Espresso"。
例如,我想从:
<clade>
<name>Espresso</name>
<branch_length>2.0</branch_length>
</clade>
Run Code Online (Sandbox Code Playgroud)
到:
<clade>
<name>Espresso</name>
<url>www.espresso.com</url>
<branch_length>2.0</branch_length>
</clade>
Run Code Online (Sandbox Code Playgroud)
根据我迄今为止所做的研究,我可以xpath用来查找包含 espresso 的节点(这应该有效,但它没有?)
import re, sys
import lxml.etree
f = open("test.xml", "r")
data = f.read()
tree = lxml.etree.XML(data)
if tree.xpath('//name/text()="Espresso"'):
insert new child here
Run Code Online (Sandbox Code Playgroud)
此时应该可以使用uselxml.etree.Element来制作xml节点,并使用insert将它们附加到xml文档中
然而,虽然这在理论上听起来很棒,但我无法让它发挥作用。
我真的很感激任何帮助/建议
您的 XPath 语句不完全正确。这是我认为你想要的:
>>> DOC = """<clade>
... <name>Espresso</name>
... <branch_length>2.0</branch_length>
... </clade>"""
>>>
>>> import lxml.etree
>>> tree = lxml.etree.XML(DOC)
>>> matches = tree.xpath('//name[text()="Espresso"]')
Run Code Online (Sandbox Code Playgroud)
然后在匹配后附加元素:
>>> for e in matches:
... sibling = lxml.etree.Element("url")
... sibling.text = "www.espresso.com"
... e.addnext(sibling)
>>> print lxml.etree.tostring(tree)
<clade>
<name>Espresso</name><url>www.espresso.com</url>
<branch_length>2.0</branch_length>
</clade>
Run Code Online (Sandbox Code Playgroud)
编辑:
由于您的文档具有命名空间,因此您希望将命名空间映射传递给 XPath 函数并使用命名空间前缀作为标记名称的前缀,如下所示:
>>> nsmap = {'phylo': 'http://www.phyloxml.org'}
>>> tree.xpath('//phylo:name[text()="Espresso"]', namespaces=nsmap)
[<Element {http://www.phyloxml.org}name at 0x2c875f0>]
Run Code Online (Sandbox Code Playgroud)