Python Lxml:添加和删除标签
我正在尝试在 xml 树中添加和删除标签(下面的片段)。我有一个布尔值字典,用于确定是否添加或删除标签。如果该值为 true,并且该元素不存在,则会创建该标记(如果不存在,则创建其父级)。如果为 false,则删除该值。
然而,它似乎不起作用,我也找不到原因。
<Assets>
<asset name="Adham">
<pos>
<x>27913.769923</x>
<y>5174.627773</y>
</pos>
<GFX>
<space>P03.png</space>
<exterior>snow.png</exterior>
</GFX>
<presence>
<faction>Dvaered</faction>
<value>10.000000</value>
<range>1</range>
</presence>
<general>
<class>P</class>
<population>100</population>
<services>
<land/>
<refuel/>
</services>
<commodities/>
<description>Fooo</description>
<bar>(null)</bar>
</general>
</asset>
</Assets>
代码:
def writeflagX(self, root, x_path, _flag):
''' Writes flag to tree: deletes if false and already exists
and adds if true but doesn't exist yet)
'''
try:
if root.xpath(x_path):
if not self.flag[_flag]:
#delete value
temp1 = root.xpath(x_path)
temp1.getparent().remove(temp1)
print "removed"
#yeah, pretty ugly
except AttributeError:
#element does not exist, so create it if true value is here
#first, see if parent tag of list items exists, create it if neccesary
#split xpath into leader and item
leader = x_path.split("/")[0]
print leader
item = x_path.split("/")[1]
try:
if root.xpath(leader): #try to see if parent tag exists
child = etree.Subelement(root.xpath(leader), item)
print "no errors"
print "not caught"
except AttributeError:
l2 = leader.split("/")[0]
print l2 + " hi"
try:
l3 = leader.split("/")[1]
if l3: #if this tag is not a direct child of the root
child1 = etree.Subelement(root.xpath(l2), l3)
child1.append(etree.Element(item))
print "no dex error"
except IndexError: #if this tag is a direct child of the root
print "dex error"
child2 = etree.SubElement(root, l2)
def writeALLflagsX(self, _root):
'''Uses writeflagX and sets all the flags
'''
for k in self.flag:
self.writeflagX(_root, self.flagPaths[k], k)
我尝试将任务标志从 false 更改为 true,并将加油标志从 true 更改为 false。
#Change Missions to true and refuel to false
foo = Asset()
###parsing code###
foo.alist["Adham"].flag["Is_missions"] = True
foo.alist["Adham"].flag["Is_refuel"] = False
foo.alist["Adham"].writeALLflagsX(foo.alist["Adham"].node)
foo.writeXML("output.xml")
我很困惑。不会添加任务标签,也不会删除加油标签。
这与我嵌套 try/ except 语句有什么关系吗?
编辑: 好的,按照建议使用 for 循环修复了删除问题:
temp1 = root.xpath(x_path)
for n in temp1:
n.getparent().remove(n)
仍然无法添加节点。
我想我要提出一个更简单的新问题,因为这太复杂了。
编辑编辑:更好的新问题:如何使用 xpath 处理添加元素及其父元素
I am attempting to add and remove tags in an xml tree (snip below). I have a dict of boolean values that I use to determine whether to add or remove a tag. If the value is true, and the element does not exist, it creates the tag (and its parent if it doesn't exist). If false, it deletes the value.
However, it doesn't seem to work, and I can't find out why.
<Assets>
<asset name="Adham">
<pos>
<x>27913.769923</x>
<y>5174.627773</y>
</pos>
<GFX>
<space>P03.png</space>
<exterior>snow.png</exterior>
</GFX>
<presence>
<faction>Dvaered</faction>
<value>10.000000</value>
<range>1</range>
</presence>
<general>
<class>P</class>
<population>100</population>
<services>
<land/>
<refuel/>
</services>
<commodities/>
<description>Fooo</description>
<bar>(null)</bar>
</general>
</asset>
</Assets>
Code:
def writeflagX(self, root, x_path, _flag):
''' Writes flag to tree: deletes if false and already exists
and adds if true but doesn't exist yet)
'''
try:
if root.xpath(x_path):
if not self.flag[_flag]:
#delete value
temp1 = root.xpath(x_path)
temp1.getparent().remove(temp1)
print "removed"
#yeah, pretty ugly
except AttributeError:
#element does not exist, so create it if true value is here
#first, see if parent tag of list items exists, create it if neccesary
#split xpath into leader and item
leader = x_path.split("/")[0]
print leader
item = x_path.split("/")[1]
try:
if root.xpath(leader): #try to see if parent tag exists
child = etree.Subelement(root.xpath(leader), item)
print "no errors"
print "not caught"
except AttributeError:
l2 = leader.split("/")[0]
print l2 + " hi"
try:
l3 = leader.split("/")[1]
if l3: #if this tag is not a direct child of the root
child1 = etree.Subelement(root.xpath(l2), l3)
child1.append(etree.Element(item))
print "no dex error"
except IndexError: #if this tag is a direct child of the root
print "dex error"
child2 = etree.SubElement(root, l2)
def writeALLflagsX(self, _root):
'''Uses writeflagX and sets all the flags
'''
for k in self.flag:
self.writeflagX(_root, self.flagPaths[k], k)
I try to change the mission flag from false to true, and the refuel flag from true to false.
#Change Missions to true and refuel to false
foo = Asset()
###parsing code###
foo.alist["Adham"].flag["Is_missions"] = True
foo.alist["Adham"].flag["Is_refuel"] = False
foo.alist["Adham"].writeALLflagsX(foo.alist["Adham"].node)
foo.writeXML("output.xml")
I am stumped. The missions tag does not get added and the refuel tag does not get deleted.
Does this have something to do with me nesting the try/except statements?
Edit:
Ok, fixed the deleting problem by using a for loop as suggested:
temp1 = root.xpath(x_path)
for n in temp1:
n.getparent().remove(n)
Still can't add a node.
I think I am going to set up a new question that is simpler, since this is too convoluted.
Edit edit: new question that is much better: How to handle adding elements and their parents using xpath
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中有几处需要改进:
node.xpath
返回节点列表 - 即您不能执行root.xpath(path).getparent()
,检查列表并获取节点#0(如果您确定它应该存在)(您的节点删除代码使用此);node.attrib
字典。使用属性变得像修改 python 字典一样简单(del node.attrib[attr]
和node.attrib[attr] = value
,确保value< /code> 是
str
);希望有帮助。
There are several things could be improved in the code:
node.xpath
returns the list of nodes - i.e. you can't doroot.xpath(path).getparent()
, check the list and take the node #0 if you're sure that it should exist (you node deletion code uses this);node.attrib
dictionary. Working with attributes becomes as easy as modifying python dictionary (del node.attrib[attr]
andnode.attrib[attr] = value
, make sure thevalue
isstr
though);etree.XML('<myelement><child/></myelement>')
for creating new nodes.Hope it helps.