Python Lxml:添加和删除标签

发布于 2024-10-30 09:57:45 字数 3412 浏览 1 评论 0原文

我正在尝试在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱的故事 2024-11-06 09:57:45

代码中有几处需要改进:

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

希望有帮助。

There are several things could be improved in the code:

  • node.xpath returns the list of nodes - i.e. you can't do root.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] and node.attrib[attr] = value, make sure the value is str though);
  • it might be useful to use etree.XML('<myelement><child/></myelement>') for creating new nodes.

Hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文