这是一个简单的模式,它声明了一个元素root
,它有一个名为foo
的布尔属性:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:attribute name="foo" type="xs:boolean" default="false"/>
</xs:complexType>
</xs:element>
</xs:schema>
这是符合架构的XML:
<?xml version="1.0"?>
<root
foo="true"
/>
这是Python代码,它解析XML并根据模式验证它:
import lxml
import lxml.etree
schema_parser = lxml.etree.XMLParser(load_dtd=True)
schema_doc = lxml.etree.parse(open('test.xsd'), parser=schema_parser)
schema = lxml.etree.XMLSchema(schema_doc)
parser = lxml.etree.XMLParser(
load_dtd=True,
dtd_validation=False,
attribute_defaults=True,
schema=schema
)
settings = lxml.etree.parse(open('test.xml'), parser=parser)
它会产生一个奇怪的异常:XMLSyntaxError: Element 'root', attribute 'foo': '' is not a valid value of the atomic type 'xs:boolean'.
。
注意'foo': ''
部分 - 这意味着,LXML认为该属性由于某种原因是空的。
为什么会这样?
P.S。 我使用LXML 3.6.4
答案 0 :(得分:0)
我可以重现,使用以下设置(在Windows 10上,Cygwin):
Python : sys.version_info(major=2, minor=7, micro=13, releaselevel='final', serial=0)
lxml.etree : (3, 7, 3, 0)
libxml used : (2, 9, 4)
libxml compiled : (2, 9, 4)
libxslt used : (1, 1, 29)
libxslt compiled : (1, 1, 29)
此外,如果我这样做
>>> x=etree.parse("testa.xml")
>>> x.getroot().attrib['foo']
结果是'true'
这已在libxml2 git repo(https://git.gnome.org/browse/libxml2/commit/?id=3169602058bd2d04913909e869c61d1540bc7fb4)中修复,如果你从那里下载源代码,编译并安装,然后从源代码重新创建lxml,这就解决了问题。
或者,恢复到libxml2-2.9.3并重新制作lxml(但可能还有其他问题...)