Как обрабатывать добавление элементов и их родителей с помощью xpath - PullRequest
4 голосов
/ 05 апреля 2011

Хорошо, у меня есть случай, когда мне нужно добавить тег к определенному другому тегу с указанным xpath.

Пример xml:

<?xml version="1.0" encoding="UTF-8"?>
<Assets>
 <asset name="Adham">
  <general>>
   <services>
    <land/>
    <refuel/>
   </services>
  </general>
 </asset>
 <asset name="Test">
  <general>
   <Something/>
  </general>
 </asset>
</Assets>

Я хочу добавить тег <missions> к обоим активам. Однако во втором ресурсе отсутствует родительский тег <services>, который я хочу добавить. Каждый тег актива хранится в переменной (скажем, node1, node2).

У меня есть следующий xpath: xpath1 = services/missions, который из-за того, как работает моя программа, я не могу просто сохранить в другой форме (т. Е. У меня нет места для хранения только services)

Мне нужно проверить и посмотреть, существует ли тег миссий, и, если это так, ничего не делать. Если тег не существует, мне нужно его создать. Если его родитель не существует, мне тоже нужно его создать.

Как я могу сделать это просто с помощью строки xpath?

Редактировать: Я хочу основать все это на булевом значении: то есть val = true, а затем создать тег (и родителя), если это необходимо. Если false, то удалите тег.

(У меня нет другого способа сослаться на нужный мне тег (поскольку у меня есть слои на слоях функций для автоматизации этого процесса в больших масштабах, вы можете проверить мой предыдущий вопрос здесь Python Lxml: Добавление и удаление тегов )).

Редактировать: еще одна проблема:

У меня нет переменной, содержащей родительский элемент добавляемого элемента, только переменная, содержащая объект <asset>. Я пытаюсь получить родительский узел нужного мне узла, используя xpath и переменную, указывающую на тег `.

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

1 Ответ

2 голосов
/ 05 апреля 2011
def to_xml(parent, xpath, value):
    """
    parent: lxml.etree.Element
    xpath: string like 'x/y/z', anything more complex is likely to break
    value: anything, if is False - means delete node
    """        
    # find the node to proceed further        
    nodes = parent.xpath(xpath)        
    if nodes:
        node = nodes[0]
    else:
        parts = xpath.split('/')
        p = parent
        for part in parts:
            nodes = p.xpath(part)
            if not nodes:
                n = etree.XML("<%s/>" % part)
                p.append(n)
                p = n
            else:
                p = nodes[0]
        node = p
    # do whatever is specified vy value
    if value is False:
        node.getparent().remove(node)
    else:
        node.text = str(value)

Хотя я не уверен, что объединение функций добавления и удаления в 1 функции является хорошей идеей, но в любом случае это может работать так, как вы ожидаете.

...