Вы можете попробовать использовать SAX-подобный интерфейс целевого парсера:
from lxml import etree
class SkipStartEndTarget:
def __init__(self, *args, **kwargs):
self.builder = etree.TreeBuilder()
self.skip = False
def start(self, tag, attrib, nsmap=None):
if tag == 'start':
self.skip = True
if not self.skip:
self.builder.start(tag, attrib, nsmap)
def data(self, data):
if not self.skip:
self.builder.data(data)
def comment(self, comment):
if not self.skip:
self.builder.comment(self)
def pi(self, target, data):
if not self.skip:
self.builder.pi(target, data)
def end(self, tag):
if not self.skip:
self.builder.end(tag)
if tag == 'end':
self.skip = False
def close(self):
self.skip = False
return self.builder.close()
Затем вы можете использовать класс SkipStartEndTarget
для создания parser target
и создать собственный XMLParser
с этой целью, например так:
parser = etree.XMLParser(target=SkipStartEndTarget())
Вы по-прежнему можете предоставить парсеру другие параметры парсера, если они вам нужны. Затем вы можете предоставить этот синтаксический анализатор используемой вами функции синтаксического анализатора, например:
elem = etree.fromstring(xml_str, parser=parser)
Это также работает с etree.XML()
и etree.parse()
, и вы даже можете установить синтаксический анализатор в качестве синтаксического анализатора по умолчанию с etree.setdefaultparser()
(что, вероятно, не очень хорошая идея). Одна вещь, которая может сбить вас с толку: даже с etree.parse()
это не вернет elementtree, а всегда будет элементом (как это делают etree.XML()
и etree.fromstring()
). Я не думаю, что это можно сделать (пока), поэтому, если это проблема для вас, вам придется как-то ее обойти.
Обратите внимание, что также можно использовать создание дерева элементов из событий sax с lxml.sax, что, вероятно, несколько сложнее и медленнее. В отличие от приведенного выше примера, он вернет elementtree, но я думаю, что он не предоставляет .docinfo
, который вы получили бы при обычном использовании etree.parse()
. Я также считаю, что он (в настоящее время) не поддерживает комментарии и пи. (еще не пользовался, поэтому точнее сказать не могу)
Также обратите внимание, что любой SAX-подобный подход к синтаксическому анализу документа требует, чтобы пропуск всего между <start/>
и <end/>
по-прежнему приводил к правильно сформированному документу, что имеет место в вашем примере, но не было бы так, если бы второй <p>
был <p2>
, например, так как в итоге получится <p>....</p2>
.
person
Steven
schedule
04.08.2010