在根元素内的元素之间解析XML文本

时间:2018-10-05 07:54:32

标签: python xml

我正在尝试用Python解析XML。这是XML结构的示例:

<a>aaaa1
 <b>bbbb</b>aaaa2
 <c>cccc</c>aaaa3
</a>

可以看到,对于根树a,它的文本为“ aaaa1”,“ aaaa2”在树b和c之间,而“ aaaa3”在c和内部a之间。我想以“ a”:{“ aaaa1”,“ aaaa2”,“ aaaa3”},“ b”:{“ bbbb”},“ c”:{“ cccc”}的方式提取文本。

这只是一个示例,因此深度/标记/节点可能更复杂,因此regex或xpath可能不起作用。 我使用了Element.text,Element.itertext()和Element.tail,但是“ aaaa2”将被视为b的尾部,而“ aaaa3”将被视为c的尾部。有没有什么方法可以将文本通常以上述方式放置?

xml = '<a>aaaa1<b>bbbb</b>aaaa2<c>cccc</c>aaaa3</a>'
parser = XMLParser(strip_cdata=False)
element = etree.fromstring(xml, parser)
for text in element.itertext():
    print(text)
for text in element.itertext(tag='a'):
    print(text)
for child in element.getchildren():
    print(child.tag, child.text, child.tail)

我暂时尝试通过以下方法来标识元素a的所有文本字段,该方法将两个文本与子元素的尾部组合在一起:

text_iter = itertools.chain([element.text], (child.tail for child in element.iterchildren()))
text_iter = (text for text in text_iter if isinstance(text, str))

由于我对XML模式结构和标准不是很熟悉,所以不确定这是否始终有效,是否还有其他更好的解决方案。

2 个答案:

答案 0 :(得分:1)

您可以创建一个函数来收集作为给定父元素的直接子元素的文本节点:

def read_element(e):
    return {e.tag: [t.strip() for t in e.xpath("text()")]}

然后在XML中的每个元素上调用该函数,并以所需的格式打印结果,例如:

print(read_element(element))
for e in element.iterdescendants():
    print(read_element(e))

答案 1 :(得分:0)

  

问题:我想以"a": {"aaaa1", "aaaa2", "aaaa3"}, "b": {"bbbb"}, "c": {"cccc"}的方式提取文本。


  

注意:如果<b>中的标签<c>xml中的标签超过一个,则必须使用一个条件!

import lxml.etree as etree

xml = '<a>aaaa1<b>bbbb</b>aaaa2<c>cccc</c>aaaa3</a>'

# Parse xml to tree
tree = etree.fromstring(xml)
#root = tree.getroot()

# In this example, the first tag is the root Element
root = tree.tag

# Init result dict with this first Element tag:[text]
result = {tree.tag:[tree.text]}

# Loop every Element in the tree
for element in tree:
    # Add this element to result tag:text
    result.setdefault(element.tag, element.text)

    # If this element has a .tail, append it to the root:[]
    if element.tail:
        result[root].append(element.tail)

print("result:{}".format(result))
>>>result:{'c': 'cccc', 'b': 'bbbb', 'a': ['aaaa1', 'aaaa2', 'aaaa3']}

使用Python测试:3.5