使用 Python 的 xml.etree 查找元素开始和结束字符偏移

Leo*_*ski 6 python xml sax elementtree

我有如下所示的 XML 数据:

<xml>
The captial of <place pid="1">South Africa</place> is <place>Pretoria</place>.
</xml>
Run Code Online (Sandbox Code Playgroud)

我希望能够提取:

  1. 目前在 etree 中提供的 XML 元素。
  2. 文档的完整纯文本,位于开始和结束标记之间。
  3. 每个起始元素在纯文本中的位置,作为字符偏移量。

(3) 是目前最重要的要求;etree 提供 (1) 罚款。

我看不出有什么方法可以直接做(3),但希望遍历文档树中的元素会返回许多可以重新组装的小字符串,从而提供(2)和(3)。但是,请求根节点的 .text 只会返回根节点和第一个元素之间的文本,例如“The capital of”。

用 SAX 做 (1) 可能涉及实现很多已经写过很多次的东西,例如 minidom 和 etree。使用 lxml 不是此代码要进入的包的选项。有人可以帮忙吗?

jfs*_*jfs 5

iterparse()功能可用于xml.etree

import xml.etree.cElementTree as etree

for event, elem in etree.iterparse(file, events=('start', 'end')):
    if event == 'start':
       print(elem.tag) # use only tag name and attributes here
    elif event == 'end':
       # elem children elements, elem.text, elem.tail are available
       if elem.text is not None and elem.tail is not None:
          print(repr(elem.tail))
Run Code Online (Sandbox Code Playgroud)

另一种选择是覆盖start(), data(),end()方法etree.TreeBuilder()

from xml.etree.ElementTree import XMLParser, TreeBuilder

class MyTreeBuilder(TreeBuilder):

    def start(self, tag, attrs):
        print("&lt;%s>" % tag)
        return TreeBuilder.start(self, tag, attrs)

    def data(self, data):
        print(repr(data))
        TreeBuilder.data(self, data)

    def end(self, tag):
        return TreeBuilder.end(self, tag)

text = """<xml>
The captial of <place pid="1">South Africa</place> is <place>Pretoria</place>.
</xml>"""

# ElementTree.fromstring()
parser = XMLParser(target=MyTreeBuilder())
parser.feed(text)
root = parser.close() # return an ordinary Element
Run Code Online (Sandbox Code Playgroud)

输出

<xml>
'\nThe captial of '
<place>
'South Africa'
' is '
<place>
'Pretoria'
'.\n'
Run Code Online (Sandbox Code Playgroud)