使用lxml分析xml时发生异常



我写这段代码是为了通过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中的文件有一个"当前位置";它从文件的开头(位置0)开始,然后,当您读取文件时,当前位置指针会一直移动,直到它到达末尾。

在lxml解析器能够完整读取内容之前,您需要将指针放回开头。使用.seek()方法:

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())的信息,请阅读Python教程中的文件对象。

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

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

而不是:

myxml = etree.parse(xmlinput)

最新更新