0

我编写了这段代码来通过 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 不是空的。问题是什么?

4

2 回答 2

3

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

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 教程中的文件对象

于 2012-07-08T11:55:38.273 回答
-1

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

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

代替:

myxml = etree.parse(xmlinput)
于 2012-07-08T11:54:13.923 回答