Python: создание различных файловых объектов при чтении файла

1

Я читаю большой файл, содержащий различные элементы <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
Теги:
file
lxml

1 ответ

1
Лучший ответ

В то время как вы не можете напрямую ответить на ваш вопрос, это может решить вашу проблему: просто добавив еще один <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
  • 0
    Да, ты прав. Тем не менее, я заинтересован в этом более «сложном» решении для лучшего изучения Python.
  • 0
    Это именно тот способ, которым я справляюсь, за исключением того, что я не использую никакие тэги, которые могут быть в узлах XML. У меня есть производственное приложение, которое выполняет xmlstr = "<doc>" + inpstr + "</ doc>"; xmldoc = etree.XML (xmlstr).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню