Добавить или добавить PI до / после элемента root с помощью lxml - PullRequest
2 голосов
/ 14 февраля 2020

С l xml, как я могу добавить инструкции обработки перед элементом root или добавить PI после элемента root с помощью l xml.

В настоящее время следующий пример не работа:

from lxml import etree

root = etree.XML("<ROOT/>")
root.addprevious(etree.ProcessingInstruction("foo"))
print(etree.tounicode(root))

Я получаю:

<ROOT/>

Вместо:

<?foo?><ROOT/>

Ответы [ 2 ]

2 голосов
/ 14 февраля 2020

Вам нужно использовать ElementTree, а не просто Element в tounicode():

from lxml import etree

root = etree.XML("<ROOT/>")
root.addprevious(etree.ProcessingInstruction("foo"))
print(etree.tounicode(root.getroottree()))

Вывод - это почти то, что вы хотели:

<?foo ?><ROOT/>

Знак пробела после foo появился, потому что lxml отображает PI как pi.target + " " + pi.text.

1 голос
/ 14 февраля 2020

На самом деле, Element всегда присоединяется к ElementTree, даже если оно выглядит «отсоединенным»:

root = etree.XML("<ROOT/>")
assert root.getroottree() is not None

Когда мы используем addprevious / addnext для вставки инструкции обработки до / после элемента root, PI не привязаны к родительскому элементу (их нет), но вместо этого они присоединены к дереву root.

Итак, проблема заключается в использовании tounicode (или tostring). Рекомендуется распечатать XML дерева root, а не элемент root.

from lxml import etree

root = etree.XML("<ROOT/>")
root.addprevious(etree.ProcessingInstruction("foo"))
root.addnext(etree.ProcessingInstruction("bar"))

print(etree.tounicode(root))
# => "<ROOT/>"

print(etree.tounicode(root.getroottree()))
# => "<?foo ?><ROOT/><?bar ?>"
...