Python Lxml: Adding and Removing Tags

I am trying to add and remove tags in the xml tree (screenshot 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 a tag (and its parent if it does not exist). If false, it removes the value.

However, it does not seem to work, and I cannot understand 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 am trying 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'm at a dead end. The mission tag is not added, and the refuel tag is not removed.

Does this have something to do with me by inserting try / except statements?

Edit: Ok, fixed the delete problem with a for loop, as suggested:

 temp1 = root.xpath(x_path) for n in temp1: n.getparent().remove(n) 

Unable to add node.

I think I'm going to ask a new question, which is simpler because it is too confusing.

Edit: a new question is much better: How to handle adding elements and their parents using xpath

0
source share
1 answer

Several things can be improved in the code:

  • node.xpath returns a list of nodes, i.e. you cannot do root.xpath(path).getparent() , check the list and take node # 0 if you are sure it should exist (you use the node delete code this);
  • when working with attributes, use the node.attrib dictionary. Working with attributes becomes as simple as changing the python dictionary ( del node.attrib[attr] and node.attrib[attr] = value , make sure value str );
  • it may be useful to use etree.XML('<myelement><child/></myelement>') to create new nodes.

Hope this helps.

+2
source

Source: https://habr.com/ru/post/1346671/


All Articles