Python Lxml: Adding and deleting tags
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 tr开发者_开发问答ue 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
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);- when working with attributes try using
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); - it might be useful to use
etree.XML('<myelement><child/></myelement>')
for creating new nodes.
Hope it helps.
精彩评论