Python Lxml:添加和删除标签

时间:2011-04-05 04:37:00

标签: python parsing exception-handling lxml

我正在尝试在xml树中添加和删除标签(下面的剪辑)。我有一个布尔值的dict,用于确定是否添加或删除标记。如果值为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)

仍然无法添加节点。

我想我会设置一个更简单的新问题,因为这太复杂了。

修改编辑:更好的新问题:How to handle adding elements and their parents using xpath

1 个答案:

答案 0 :(得分:2)

代码中有几件事可以改进:

  • node.xpath返回节点列表 - 即你不能root.xpath(path).getparent(),检查列表并取出节点#0,如果你确定它应该存在(节点删除代码使用)本);
  • 使用属性时尝试使用node.attrib字典。使用属性变得像修改python字典(del node.attrib[attr]node.attrib[attr] = value一样简单,确保value虽然是str;
  • 使用etree.XML('<myelement><child/></myelement>')创建新节点可能很有用。

希望它有所帮助。