Python Lxml: добавление и удаление тегов - PullRequest
0 голосов
/ 05 апреля 2011

Я пытаюсь добавить и удалить теги в дереве 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 / исключением?

Редактировать: ОК, исправлено удалениепроблема с использованием цикла for, как было предложено:

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

Все еще не могу добавить узел.

Я думаю, что собираюсь задать новый вопрос, который проще, так как этоСлишком запутанный.

Редактировать редактировать: новый вопрос, который намного лучше: Как обрабатывать добавление элементов и их родителей, используя xpath

1 Ответ

2 голосов
/ 05 апреля 2011

В коде можно улучшить несколько вещей:

  • 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>') для созданияузлы.

Надеюсь, это поможет.

...