How to add xml node depending on node text value

I play with the found xml file @ http://www.jsphylosvg.com/examples/source.php?example=2&t=xml

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

eg. I would like to change:

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

in

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

Based on the research I have done so far, I can use xpath to search for a node that contains espresso (should this work, but is it 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 lxml.etree.Element to create the xml node and use the insert to attach them to the XML document

However, although that sounds great in theory, I can't get it to work.
I would really appreciate any help / suggestions.

+4
source share
1 answer

Your XPath statement is not quite right. Here is 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 add the item after 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 the namespace map to the XPath function and the tag name prefix with the namespace prefix, for example:

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

All Articles