I am playing around with an xml file found @ 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"
.
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?)
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
However, while this sounds great in theory, I am unable to get it to work.
I would really appreciate any help/suggestions
Your XPath statement is not exactly right. Here's what I think you want:
>>> 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:
>>> nsmap = {'phylo': 'http://www.phyloxml.org'}
>>> tree.xpath('//phylo:name[text()="Espresso"]', namespaces=nsmap)
[<Element {http://www.phyloxml.org}name at 0x2c875f0>]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With