2012-03-21 135 views
4

我正在使用python xmlElementTree,并且想根据它的属性来分配或修改xml元素值。有人可以给我一个想法如何做到这一点?根据其属性找到xml元素并更改其值

例如:这里是xml文件,我需要根据属性“sys/phoneNumber/1”,“sys2/SMSnumber/1”等设置元素“number”的值。

<root> 
    <phoneNumbers> 
     <number topic="sys/phoneNumber/1" update="none" /> 
     <number topic="sys/phoneNumber/2" update="none" /> 
     <number topic="sys/phoneNumber/3" update="none" /> 
    </phoneNumbers> 

    <gfenSMSnumbers> 
     <number topic="sys2/SMSnumber/1" update="none" /> 
     <number topic="sys2/SMSnumber/2" update="none" /> 
    </gfenSMSnumbers> 
    </root> 

编辑:在XML文件中为标记根添加了闭包。

回答

1

我不熟悉xmlElementTree,但如果你使用能够xpath表达的东西,你可以用这样的表达定位由属性值的节点:

//number[@topic="sys/phoneNumber/1"] 

因此,使用etree模块:

>>> import lxml.etree as etree 
>>> doc = etree.parse('foo.xml') 
>>> nodes = doc.xpath('//number[@topic="sys/phoneNumber/1"]') 
>>> nodes 
[<Element number at 0x10348ed70>] 
>>> etree.tostring(nodes[0]) 
'<number topic="sys/phoneNumber/1" update="none"/>\n ' 
9

可以为这种访问属性值:

from elementtree.ElementTree import XML, SubElement, Element, tostring 

text = """ 
<root> 
    <phoneNumbers> 
     <number topic="sys/phoneNumber/1" update="none" /> 
     <number topic="sys/phoneNumber/2" update="none" /> 
     <number topic="sys/phoneNumber/3" update="none" /> 
    </phoneNumbers> 

    <gfenSMSnumbers> 
     <number topic="sys2/SMSnumber/1" update="none" /> 
     <number topic="sys2/SMSnumber/2" update="none" /> 
    </gfenSMSnumbers> 
</root> 
""" 

elem = XML(text) 
for node in elem.find('phoneNumbers'): 
    print node.attrib['topic'] 
    # Create sub elements 
    if node.attrib['topic']=="sys/phoneNumber/1": 
     tag = SubElement(node,'TagName') 
     tag.attrib['attr'] = 'AttribValue' 

print tostring(elem) 

忘了说,如果你的ElementTree的版本大于1.3,你可以使用XPath:

elem.find('.//number[@topic="sys/phoneNumber/1"]') 

http://effbot.org/zone/element-xpath.htm

,或者你可以使用这个简单的一个:

for node in elem.findall('.//number'): 
    if node.attrib['topic']=="sys/phoneNumber/1": 
     tag = SubElement(node,'TagName') 
     tag.attrib['attr'] = 'AttribValue' 
+0

您展示了如何定位元素并修改属性,但他询问如何修改元素。我认为你的最后一行应该是: tag.text ='new value' – Spaceghost 2012-03-21 01:50:53

+0

是的,我没有修改元素的值...创建一个新的标签并赋值:'tag.text ='new value''或修改元素值:'node.text ='new value'' – focusheart 2012-03-21 02:17:59

+0

如果我想使用xml文件作为输入而不是文本,该怎么办? – user1282251 2012-03-21 03:18:21

0

larsks解释如何使用XPath很好地找到你所需要的。你也想改变一个属性。最好的方法可能是添加一个新属性并删除原来的。一旦得到节点结果,它就是一个包含单个条目(数字)的列表。

# This returns sys/phoneNumber/1 
nodes[0].get("topic") 
# To change the value, use set 
nodes[0].set("topic", "new/value/of/phone/number") 

希望这会有所帮助。

此外,您的结束根标记不能正确关闭。