Получить весь текст родительского тега в ElementTree - PullRequest
1 голос
/ 06 марта 2020

При использовании пакета xml.etree.ElementTree as ET python я хотел бы получить весь текст в теге XML, который содержит несколько дочерних узлов. Рассмотрим следующее xml:

<p>This is the start of parent tag...
        <ref type="chlid1">child 1</ref>. blah1 blah1 blah1 <ref type="chlid2">child2</ref> blah2 blah2 blah2 
</p>

Если предположить, что вышеприведенный XML находится в node, то node.text даст мне This is the start of parent tag.... Однако я хочу захватить весь текст внутри тега p (вместе с текстами его дочернего тега), что приведет к: This is the start of parent tag... child 1. blah1 blah1 blah1 child2 blah2 blah2 blah2.

Есть ли обходной путь для этой проблемы? Я изучил документацию, но не смог найти то, что сработало.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Вы можете сделать что-то похожее с ElementTree:

import xml.etree.ElementTree as ET
data = """[your string above]"""
tree = ET.fromstring(data)
print(' '.join(tree.itertext()).strip())

Вывод:

This is the start of parent tag...
         child 1 . blah1 blah1 blah1  child2  blah2 blah2 blah2
1 голос
/ 06 марта 2020

Это действительно очень неловкая особенность ElementTree. Суть заключается в следующем: если элемент содержит как текстовые, так и дочерние элементы, и если дочерний элемент находится между различными промежуточными текстовыми узлами, то текст после дочернего элемента называется tail этого элемента вместо text. * 1003. *

Чтобы собрать весь текст, который является непосредственным потомком или потомком элемента, вам необходимо получить доступ к text и tail этого элемента и всех элементов-потомков.

>>> from lxml import etree

>>> s = '<p>This is the start of parent tag...<ref type="chlid1">child 1</ref>. blah1 blah1 blah1 <ref type="chlid2">child2</ref> blah2 blah2 blah2 </p>'

>>> root = etree.fromstring(s)
>>> child1, child2 = root.getchildren()

>>> root.text
'This is the start of parent tag...'

>>> child1.text, child1.tail
('child 1', '. blah1 blah1 blah1 ')

>>> child2.text, child2.tail
('child2', ' blah2 blah2 blah2 ')

Что касается законченного решения, я обнаружил, что этот ответ делает что-то очень похожее, что вы можете легко приспособиться к своему сценарию использования (не печатая названия элементов).


Редактировать : на самом деле, на мой взгляд, самое простое решение - - использовать itertext :

>>> ''.join(root.itertext())
'This is the start of parent tag...child 1. blah1 blah1 blah1 child2 blah2 blah2 blah2 '
...