Я читаю большой файл, содержащий различные элементы <xml>..</xml>
. Поскольку каждый анализатор XML имеет проблемы с этим, я хотел бы создать эффективно новые файловые объекты для каждого блока <xml>..</xml>
.
Я начал подклассифицировать файл-объект в 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