Python и ElementTree: возвращают «внутренний XML», исключая родительский элемент - PullRequest
12 голосов
/ 10 августа 2010

В Python 2.6 с использованием ElementTree, каков хороший способ извлечь XML (в виде строки) внутри определенного элемента, например, что вы можете сделать в HTML и javascript с помощью innerHTML?

Вот упрощенный пример узла XML, с которого я начинаю:

<label attr="foo" attr2="bar">This is some text <a href="foo.htm">and a link</a> in embedded HTML</label>

Я хотел бы получить следующую строку:

This is some text <a href="foo.htm">and a link</a> in embedded HTML

I 'мы пытались перебрать родительский узел и объединить tostring() дочерних элементов, но это дало мне только подузлы:

# returns only subnodes (e.g. <a href="foo.htm">and a link</a>)
''.join([et.tostring(sub, encoding="utf-8") for sub in node])

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

re.sub("</\w+?>\s*?$", "", re.sub("^\s*?<\w*?>", "", et.tostring(node, encoding="utf-8")))

Ответы [ 3 ]

10 голосов
/ 10 августа 2010

Как насчет:

from xml.etree import ElementTree as ET

xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>'
root = ET.fromstring(xml)

def content(tag):
    return tag.text + ''.join(ET.tostring(e) for e in tag)

print content(root)
print content(root.find('child2'))

В результате:

start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here
here as well<sub2 /><sub3 />
1 голос
/ 01 июля 2018

Это основано на других решениях, но другие решения не работали в моем случае (приводили к исключениям), и это работало:

from xml.etree import Element, ElementTree

def inner_xml(element: Element):
    return (element.text or '') + ''.join(ElementTree.tostring(e, 'unicode') for e in element)

Используйте его так же, как в Марк Толонен, ответ .

1 голос
/ 10 августа 2010

Для меня сработало следующее:

from xml.etree import ElementTree as etree
xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>'
dom = etree.XML(xml)

(dom.text or '') + ''.join(map(etree.tostring, dom)) + (dom.tail or '')
# 'start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here'

dom.text or '' используется для получения текста в начале элемента root.Если текст отсутствует dom.text - это None.

Обратите внимание, что результат не является допустимым XML - допустимый XML должен иметь только один корневой элемент. ElementTree документирует смешанное содержимое .


Использование Python 2.6.5, Ubuntu 10.04

...