从 libxml2 2.6 升级到 2.7 时,我的某些行为发生了变化。我在他们的网站上找到了关于此更改的错误报告,其https://bugzilla.gnome.org/show_bug.cgi?id=571271。
有趣的是,他们报告说“我猜我们误解了这个选项的预期行为(尽管我仍然不是 100% 确定)”——他们不确定他们是否正确阅读了规范,但他们提交了修复程序。
我认为以前的行为是正确的,所以我想看看这里是否有人对这两个方向有了解。
基本上,是否<xs:all>elem1, elem2, ..<xs:all>
意味着“必须存在 elem1、elem2 .. 中的所有或不存在”,或“可能存在 elem1、elem2 中的任何一个 ..”?尽管看起来像前者,但有两个消息来源并没有说明这一点:
http://www.w3.org/TR/xmlschema-0/#ref18 - “组中的所有元素可能出现一次,也可能根本不出现,它们可能以任何顺序出现。”
http://www.w3schools.com/Schema/el_all.asp - “上面的例子表明“名字”和“姓氏”元素可以以任何顺序出现,每个元素可以出现零次或一次!”
下面的脚本使用 lxml,在使用 libxml2 2.6 时报告成功,但第二个模式验证在 2.7 上失败。有人可以确认 2.7 在这里做的是对还是错?
from lxml import etree
from StringIO import StringIO
schema = """
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element type="parent-type" name="parent"/>
<xs:complexType name="parent-type">
<xs:all maxOccurs="1" minOccurs="0">
<xs:element type="xs:int" name="int-attr"/>
<xs:element type="xs:string" name="str-attr"/>
</xs:all>
</xs:complexType>
</xs:schema>
"""
xmlschema = etree.XMLSchema(etree.parse(StringIO(schema)))
# passes
doc1 = """
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
<str-attr>some value</str-attr>
<int-attr>12</int-attr>
</parent>
"""
# fails. it wants both "int-attr" and "str-attr" to be present.
# didn't think this was how "xs:all" worked ?
doc2 = """
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
<int-attr>12</int-attr>
</parent>
"""
for i, doc in enumerate((doc1, doc2, )):
doc = etree.parse(StringIO(doc))
try:
xmlschema.assertValid(doc)
print "document %d is valid." % i
except Exception, e:
print "document %d is not valid." % i
print e
Run Code Online (Sandbox Code Playgroud)
输出:
document 0 is valid.
document 1 is not valid.
Element 'parent': Missing child element(s). Expected is ( str-attr )., line 2
Run Code Online (Sandbox Code Playgroud)
用户 Jörn Horstmann 实际上已经正确回答了您的问题,但格式可能会使答案看起来有点不清楚。我希望这些例子能帮助那些感到困惑的人。
minOccurs
和maxOccurs
意义<xs:all>
请记住这一点,<xs:all>
并<xs:element>
为minOccurs
和设置默认值“1” maxOccurs
。所以
<xs:all>
<xs:element type="xs:int" name="int-attr"/>
<xs:element type="xs:string" name="str-attr"/>
</xs:all>
Run Code Online (Sandbox Code Playgroud)
实际上是一样的
<xs:all minOccurs="1" maxOccurs="1">
<xs:element type="xs:int" name="int-attr" minOccurs="1" maxOccurs="1"/>
<xs:element type="xs:string" name="str-attr" minOccurs="1" maxOccurs="1"/>
</xs:all>
Run Code Online (Sandbox Code Playgroud)
这意味着整个<xs:all>
组以及其中定义的两个元素都是强制性的 - 订单是自由的。因此 XML 文档
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
<int-attr>12</int-attr>
</parent>
Run Code Online (Sandbox Code Playgroud)
将无效。使用属性minOccurs="0"
on<xs:all>
意味着整个组是可选的,在这种情况下它也允许一个空<parent/>
元素。我看到这就是规范的真正含义“组中的所有元素可能出现一次或根本不出现”。我的母语不是英语,但我也想说 w3schools 页面上的第二个例子是不正确的。它应该读作“两个元素都可以出现零次或一次”而不是“每个元素都可以出现零次或一次”。
maxOccurs
的属性<xs:all>
被固定为值“1”。
所以这就是您在评论中提出的问题以及您首先尝试验证的内容。<xs:all>
组内的可选元素是通过minOccurs="0"
在这些元素上添加属性来实现的。下面的例子
<xs:all minOccurs="1" maxOccurs="1">
<xs:element type="xs:int" name="int-attr" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="str-attr" minOccurs="0" maxOccurs="1"/>
</xs:all>
Run Code Online (Sandbox Code Playgroud)
此模式将验证 XML 文档
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
<int-attr>12</int-attr>
</parent>
Run Code Online (Sandbox Code Playgroud)
由于这两个元素都是可选的(因为它们有minOccurs="0"
),这个定义也允许一个空<parent/>
元素。尽管对元素的基数限制以某种方式“覆盖”了<xs:all>
规范中设置的基数限制也说:“内容模型中的元素不能出现多次,即 minOccurs 和 maxOccurs 的允许值是 0 和 1”。所以你不能有一个以随机顺序多次具有相同元素的组,或者至少你不能<xs:all>
用来创建这样的类型。
归档时间: |
|
查看次数: |
2397 次 |
最近记录: |