2012-08-13 68 views
4

我玩弄發現@http://www.jsphylosvg.com/examples/source.php?example=2&t=xml如何添加基於文本節點

的XML文件的值的XML節點我想插入一個節點,如果節點name="Espresso"的價值。

E.g.我想改變來自:

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

到:

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

基於迄今爲止我可以使用xpath查找包含咖啡(這應該工作的節點我也做了研究,但它不?)

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 

在這一點上,它應該是可以使用使用lxml.etree.Element使XML沒有de,並使用插入將它們附加到xml文檔中

但是,雖然這在理論上聽起來很好,但我無法使其工作。
我真的很感激任何幫助/建議

回答

3

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

然後在比賽後的元素追加:

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

編輯:

由於您的文檔有一個命名空間,你想傳遞一個名稱空間映射到XPath函數,並將標籤名稱作爲名稱空間前綴的前綴,如下所示:

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

謝謝。代碼很好用你的示例DOC。但是,使用實際的文件它似乎沒有工作。 – Stylize 2012-08-13 02:54:57

+0

@Stylize - 它可能失敗,因爲實際的文件有一個默認的命名空間。 – 2012-08-13 03:32:45

+1

@DevNull,這是否意味着它無法完成? – Stylize 2012-08-13 11:45:25