我正在阅读一个大文件,其中包含各种 <xml>..</xml>
元素。由于每个 XML 解析器都遇到了这个问题,我想为每个 <xml>..</xml>
生成有效的新文件对象。 block 。
我开始在 Python 中对文件对象进行子类化,但陷入了困境。我想,我必须拦截以 </xml>
开头的每一行并返回一个新的文件对象;也许通过使用 yield
.
有人可以指导我朝正确的方向迈出这一步吗?
这是我当前的代码片段:
#!/bin/bash/env python
from lxml import etree
from StringIO import StringIO
class handler(file):
def __init__(self, name, mode):
file.__init__(self, name, mode)
def next(self):
return file.next(self)
def listXmls(self):
output = StringIO()
line = self.next()
while line is not None:
output.write(line.strip())
if line.strip() == '</xml>':
yield output
output = StringIO()
try:
line = self.next()
except StopIteration:
break
output.close()
f = handler('myxml.xml', 'r')
for elem in f.listXmls():
print 'm' + elem.getvalue() + 'm'
context = etree.iterparse(elem, events=('end',), tag='id')
for event, element in context:
print element.tag
谢谢!
解决方案(仍然对更好的版本感兴趣):
#!/bin/bash/env python
from lxml import etree
from StringIO import StringIO
class handler(file):
def __init__(self, name, mode):
file.__init__(self, name, mode)
def next(self):
return file.next(self)
def listXmls(self):
output = StringIO()
output.write(self.next())
line = self.next()
while line is not None:
if line.startswith('<?xml'):
output.seek(0)
yield output
output = StringIO()
output.write(line)
try:
line = self.next()
except StopIteration:
break
output.seek(0)
yield output
f = handler('myxml.xml', 'r')
for elem in f.listXmls():
context = etree.iterparse(elem, events=('end',), tag='id')
for event, element in context:
print element.tag
最佳答案
虽然不是直接回答您的问题,但这可能会解决您的问题:只需添加另一个 <xml>
在开始和另一个 </xml>
最后可能会让您的 XML 解析器接受该文档:
from lxml import etree
document = "<xml>a</xml> <xml>b</xml>"
document = "<xml>" + document + "</xml>"
for subdocument in etree.XML(document):
# whatever
关于Python:读取文件时创建各种文件对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6348946/