繁体   English   中英

通过lxml.etree.iterparse解析单个文件中的几个XML声明

[英]Parse several XML declarations in a single file by means of lxml.etree.iterparse

我需要解析一个包含各种XML文件的文件,即<xml> </ xml> <xml> </ xml> ..等等。 使用etree.iterparse时,出现以下(正确)错误:

lxml.etree.XMLSyntaxError: XML declaration allowed only at the start of the document

现在,我可以预处理输入文件,并为每个包含的XML文件生成一个单独的文件。 这可能是最简单的解决方案。 但是我想知道是否存在针对此“问题”的适当解决方案。

谢谢!

您提供的样本数据提示了一个问题,而您提供的问题和异常提示了另一个问题。 您是否有多个串联在一起的XML文档,每个文档都有自己的XML声明,或者您是否有一个包含多个顶级元素的XML片段?

如果是前者,则解决方案将涉及将输入流分成多个流,并分别解析每个流。 正如一个评论所暗示的,这并不一定意味着实现XML解析器。 您可以在字符串中搜索XML声明,而不必解析其中的任何其他内容,只要您的输入不包括包含未转义XML声明的CDATA部分即可。 您可以编写一个类似文件的对象,该对象从基础流返回字符,直到命中XML声明为止,然后将其包装在生成器函数中,该函数一直返回流,直到到达EOF。 这不是微不足道的,但是也不是那么困难。

如果您有一个包含多个顶级元素的XML片段,则可以将它们包装为一个XML元素并解析整个内容。

当然,与涉及不良XML输入的大多数问题一样,最简单的解决方案可能就是修复产生不良输入的问题。

我用正则表达式解决了这个问题。 假设数据是一个包含多个xml文档的字符串,并且该句柄是一个将对每个文档执行某些操作的函数。 执行此循环后,数据将为空,或包含不完整的XML文档,并且句柄函数将被调用零次或多次。

while True:
  match = re.match (r'''
        \s*                 # ignore leading whitespace
        (                   # start first group
          <(?P<TAG>\S+).*?> # opening tag (with optional attributes)
            .*?             # stuff in the middle
          </(?P=TAG)>       # closing tag
        )                   # end of first xml document
        (?P<REM>.*)         # anything else
      ''',
    data, re.DOTALL | re.VERBOSE)
  if not match:
    break
  document = match.group (1)
  handle (document)
  data = match.group ('REM')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM