【问题标题】:Exception when parsing a xml using lxml使用 lxml 解析 xml 时出现异常
【发布时间】:2012-07-08 11:51:48
【问题描述】:

我编写这段代码是为了通过 xsd 验证我的 xml 文件

def parseAndObjectifyXml(xmlPath, xsdPath):
    from lxml import  etree

    xsdFile = open(xsdPath)
    schema = etree.XMLSchema(file=xsdFile)
    xmlinput = open(xmlPath)
    xmlContent = xmlinput.read()
    myxml = etree.parse(xmlinput) # In this line xml input is empty
    schema.assertValid(myxml)

但是当我想验证它时,我的 xmlinput 是空的,但我的 xmlContent 不是空的。 有什么问题?

【问题讨论】:

  • 供将来参考:如果您确实在 Python 中遇到异常,则会有回溯。如果您在问题中包含该回溯(完整),我们将更容易为您提供帮助。
  • @MartijnPieters 但它没有任何追溯
  • 那么也没有异常;你的问题标题建议有。

标签: python xml xml-parsing lxml


【解决方案1】:

python 中的文件有一个“当前位置”;它从文件的开头(位置 0)开始,然后,当您读取文件时,当前位置指针会一直移动,直到它到达结尾。

您需要将该指针放回到开头,然后 lxml 解析器才能完整读取内容。为此使用.seek() method

from lxml import  etree

def parseAndObjectifyXml(xmlPath, xsdPath):
    xsdFile = open(xsdPath)
    schema = etree.XMLSchema(file=xsdFile)
    xmlinput = open(xmlPath)
    xmlContent = xmlinput.read()
    xmlinput.seek(0)
    myxml = etree.parse(xmlinput)
    schema.assertValid(myxml)

仅当您在其他地方也需要xmlContent 时才需要这样做;如果包装在StringIO 对象中,您也可以将其传递给.parse() 方法以提供必要的文件对象方法:

from lxml import  etree
from cStringIO import StringIO

def parseAndObjectifyXml(xmlPath, xsdPath):
    xsdFile = open(xsdPath)
    schema = etree.XMLSchema(file=xsdFile)
    xmlinput = open(xmlPath)
    xmlContent = xmlinput.read()
    myxml = etree.parse(StringIO(xmlContent))
    schema.assertValid(myxml)

如果您xmlContent 用于其他任何事情,那么您也不需要额外的.read() 调用,并且随后使用lxml 解析它不会有问题;只需完全省略调用,您也不需要将当前位置指针移回起点:

from lxml import  etree

def parseAndObjectifyXml(xmlPath, xsdPath):
    xsdFile = open(xsdPath)
    schema = etree.XMLSchema(file=xsdFile)
    xmlinput = open(xmlPath)
    myxml = etree.parse(xmlinput)
    schema.assertValid(myxml)

要了解有关.seek()(及其对应的.tell())的更多信息,请read up on file objects in the Python tutorial

【讨论】:

    【解决方案2】:

    您应该使用已阅读的 XML 内容:

    xmlContent = xmlinput.read()
    myxml = etree.parse(xmlContent)
    

    代替:

    myxml = etree.parse(xmlinput)
    

    【讨论】:

    • 误读了我的误读,事实证明我是正确的,但这个答案仍然是错误的。您无法解析字符串中的 XML 内容; lxml etree.parse 会将其解释为文件名,这将失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多