使用ElementTree顺序解析某些XML标签

问题描述 投票:1回答:1

我正在尝试以顺序方式解析XML文件,仅考虑感兴趣的XML标签。下面显示了一个示例XML文件(存储为file.xml)。我只对某些已知路径的XML标签感兴趣,如下面的Python代码片段所示(例如header / para / paratextbody / section / intro / text)。不同的XML文件可能具有不同的标记顺序,因此我不想规定已知的XML标记将以哪个顺序出现。关于如何有效地做到这一点的任何建议,而不必遍历整个XML文件?

XML文件

<data>
  <header>
    <para>
      <paratext>0 - extract this</paratext>
    </para>
  </header>
  <body>
    <section>
      <intro>
        <text>1 - extract this</text>
      </intro>
      <para>
        <paratext>2 - extract this</paratext>
      </para>
      <items>
        <paratext>do not extract this</paratext>
        <part>
          <para>
            <paratext>3 - extract this</paratext>
          </para>
        </part>
      </items>
    </section>
    <section>
      <text>do not extract this</text>
      <intro>
        <text>4 - extract this</text>
      </intro>
      <para>
        <paratext>5 - extract this</paratext>
      </para>
      <para>
        <paratext>6 - extract this</paratext>
      </para>
    </section>
  </body>
</data>

所需的输出['0 - extract this', '1 - extract this', '2 - extract this', '3 - extract this', '4 - extract this', '5 - extract this', '6 - extract this']

样本Python脚本

import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()

### Paths I would like to extract (but sequentially)
[i.text for i in root.findall('header/para/paratext')]
# ['0 - extract this']
[i.text for i in root.findall('body/section/intro/text')]
# ['1 - extract this', '4 - extract this']
[i.text for i in root.findall('body/section/para/paratext')]
# ['2 - extract this', '5 - extract this', '6 - extract this']
[i.text for i in root.findall('body/section/items/part/para/paratext')]
# ['3 - extract this']
python xml xml-parsing elementtree
1个回答
0
投票

我认为最好的方法是使用union operator ("|") in XPath。这将按文档顺序选择所需的元素。

不幸的是,ElementTree具有|

如果可以使用lxml,则它具有limited XPath support

示例...

Python

much better XPath support

打印输出

from lxml import etree

tree = etree.parse("file.xml")

print([i.text for i in tree.xpath('header/para/paratext|'
                                  'body/section/intro/text|'
                                  'body/section/para/paratext|'
                                  'body/section/items/part/para/paratext')])
© www.soinside.com 2019 - 2024. All rights reserved.