这是一个简单的XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<someThing>
Text A: This is a test line.
<p>Some paragraph.</p>
Text B: This is another test line.
<p>Some other paragraph.</p>
Text C: And even another test line.
</someThing>
</root>
尽管测试XML文件非常小,但我要处理的实际文件却相当大:几GB。因此,我想使用以下Python代码使用iterparse()解析此文件。
import xml.etree.ElementTree as etree
FILE_NAME = "test.xml"
for event, element in etree.iterparse(FILE_NAME, events=("start", "end", "start-ns", "end-ns")):
print(event, "\t", element, "\t", repr(element.text))
如果运行此命令,则会得到以下输出:
start <Element 'root' at 0x7fd96a6aa728> '\n\t'
start <Element 'someThing' at 0x7fd968fba688> '\n\t\tText A: This is a test line.\n\t\t'
start <Element 'p' at 0x7fd968fcaf48> 'Some paragraph.'
end <Element 'p' at 0x7fd968fcaf48> 'Some paragraph.'
start <Element 'p' at 0x7fd968fcaf98> 'Some other paragraph.'
end <Element 'p' at 0x7fd968fcaf98> 'Some other paragraph.'
end <Element 'someThing' at 0x7fd968fba688> '\n\t\tText A: This is a test line.\n\t\t'
end <Element 'root' at 0x7fd96a6aa728> '\n\t'
您会看到<p>
元素之后的文本元素被忽略。
我的问题是:我该如何使用LXML API正确处理此文件的内容?到目前为止,我能找到的与该主题有关的所有示例都与我的短代码没什么不同,因此也遇到了相同的问题。如果无法使用LXML做到这一点,那么有人知道我可以使用其他XML解析器吗,并提供一个简短的示例吗?
答案 0 :(得分:0)
根据用户mzjn
的友好注释,可以使用LXML进行操作:有一个tail
属性,缺少的文本将附加到该属性。但这可能不是最佳方法,原因如下:
tail
来解决此问题。替代解决方案:直接使用SAX API。
示例:
import xml.sax
FILE_NAME = "test.xml"
class MyHandler(xml.sax.handler.ContentHandler):
def startElement(self, name, attrs):
print("startElement\t" + repr(name))
def endElement(self, name):
print("endElement\t" + repr(name))
def startElementNS(self, name, qname, attrs):
print("startElementNS\t" + repr(name))
def endElementNS(self, name, qname):
print("endElementNS\t" + repr(name))
def characters(self, content):
print(" chars\t\t" + repr(content))
contentHandler = MyHandler()
xml.sax.parse(FILE_NAME, contentHandler)
上面的示例将是处理大型XML文件的一个很好的起点。方法characters()
将为每个已解析的文本调用。实体被解码并导致对characters()
的调用,因此很容易收集存储在XML元素上的所有文本。如果您实现了一个简单的堆栈,该堆栈在内容处理程序中对startElement()
和endElement()
的调用上会增加和减少,则可以轻松解析树的特定部分,而无需处理。< / p>