如何根据文本节点的值添加xml节点

时间:2021-09-30 08:21:20

I am playing around with an xml file found @ http://www.jsphylosvg.com/examples/source.php?example=2&t=xml

我正在玩一个xml文件@ http://www.jsphylosvg.com/examples/source.php?example=2&t=xml

I would like to insert a node if the value of the node name="Espresso".

如果节点名称的值=“Espresso”,我想插入一个节点。

E.g. I would like to change from:

例如。我想改变自:

<clade>
<name>Espresso</name>
<branch_length>2.0</branch_length>
</clade>

to:

<clade>
<name>Espresso</name>
<url>www.espresso.com</url>
<branch_length>2.0</branch_length>
</clade>

Based on the research I have done thus far I can use xpath to find the node that contains espresso (this should work, but it does not?)

根据我迄今为止所做的研究,我可以使用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

At this point, it should be possible to use use lxml.etree.Element to make the xml node, and use insert to attach them into xml document

此时,应该可以使用lxml.etree.Element来创建xml节点,并使用insert将它们附加到xml文档中

However, while this sounds great in theory, I am unable to get it to work.
I would really appreciate any help/suggestions

然而,虽然这在理论上听起来很棒,但我无法让它发挥作用。我真的很感激任何帮助/建议

1 个解决方案

#1


3  

Your XPath statement is not exactly right. Here's what I think you want:

您的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"]')

Then to append the element after the matches:

然后在匹配后追加元素:

>>> 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>

EDIT:

Since your document has a namespace, you want to pass a namespace map to the XPath function and prefix the tag name with the namespace prefix, like this:

由于您的文档具有命名空间,因此您希望将命名空间映射传递给XPath函数,并在标记名称前加上命名空间前缀,如下所示:

>>> nsmap = {'phylo': 'http://www.phyloxml.org'}
>>> tree.xpath('//phylo:name[text()="Espresso"]', namespaces=nsmap)
[<Element {http://www.phyloxml.org}name at 0x2c875f0>]

#1


3  

Your XPath statement is not exactly right. Here's what I think you want:

您的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"]')

Then to append the element after the matches:

然后在匹配后追加元素:

>>> 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>

EDIT:

Since your document has a namespace, you want to pass a namespace map to the XPath function and prefix the tag name with the namespace prefix, like this:

由于您的文档具有命名空间,因此您希望将命名空间映射传递给XPath函数,并在标记名称前加上命名空间前缀,如下所示:

>>> nsmap = {'phylo': 'http://www.phyloxml.org'}
>>> tree.xpath('//phylo:name[text()="Espresso"]', namespaces=nsmap)
[<Element {http://www.phyloxml.org}name at 0x2c875f0>]