XML 的 XSD 验证失败
Posted
技术标签:
【中文标题】XML 的 XSD 验证失败【英文标题】:XSD verification for XML fails 【发布时间】:2019-05-18 13:07:52 【问题描述】:我有一个 XML 文件,其内容如下
<?xml version="1.0" encoding="UTF-8"?>
<SETTINGS Version="1">
<CLEANING amount="40"/>
<CLEANING name="abcd"/>
<CLEANING initials="ABCD"/>
<MAINTENANCE state="on"/>
<MAINTENANCE temperature="F"/>
</SETTINGS>
我使用一些生成以下 XSD 输出的工具为此 XML 创建了 XSD 架构。
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SETTINGS">
<xs:complexType>
<xs:sequence>
<xs:element name="CLEANING" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="amount" type="xs:unsignedByte" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="initials" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="MAINTENANCE" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="state" type="xs:string" use="required" />
<xs:attribute name="temperature" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Version" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
现在,当我尝试根据生成的 XSD 架构验证此 XMl 时,我得到以下验证错误(使用某些在线验证器验证)。
Not valid.
Error - Line 3, 24: org.xml.sax.SAXParseException; lineNumber: 3; columnNumber: 24; cvc-complex-type.4: Attribute 'name' must appear on element 'CLEANING'.
Error - Line 3, 24: org.xml.sax.SAXParseException; lineNumber: 3; columnNumber: 24; cvc-complex-type.4: Attribute 'initials' must appear on element 'CLEANING'.
Error - Line 4, 24: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 24; cvc-complex-type.4: Attribute 'amount' must appear on element 'CLEANING'.
Error - Line 4, 24: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 24; cvc-complex-type.4: Attribute 'initials' must appear on element 'CLEANING'.
Error - Line 5, 28: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 28; cvc-complex-type.4: Attribute 'amount' must appear on element 'CLEANING'.
Error - Line 5, 28: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 28; cvc-complex-type.4: Attribute 'name' must appear on element 'CLEANING'.
Error - Line 6, 26: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 26; cvc-complex-type.4: Attribute 'temperature' must appear on element 'MAINTENANCE'.
Error - Line 7, 31: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 31; cvc-complex-type.4: Attribute 'state' must appear on element 'MAINTENANCE'.
XML 和 XSD 都是经过在线验证的有效格式。我无法理解此错误背后的原因。我怀疑这是因为有多个元素共享相同的名称,我认为在生成 XSD 模式时存在一些限制。不知道到底出了什么问题。
我在这里做错了什么,有什么办法可以解决这个错误?
【问题讨论】:
【参考方案1】:<xs:complexType>
<xs:attribute name="amount" type="xs:unsignedByte" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="initials" type="xs:string" use="required" />
</xs:complexType>
单词
require
表示需要该属性,因此您的XML 的正确书写是:
<CLEANING amount="40" name="abcd" initials="ABCD"/>
如果你想让你写你需要删除你的 XSD 的require
维护也是如此
您的 XSD 验证此文本:
<SETTINGS Version="1">
<CLEANING amount="40" name="abcd" initials="ABCD"/>
<MAINTENANCE state="on" temperature="F"/>
</SETTINGS>
但是如果你想用这种外观来验证你的 XML 是不可能把use=require
所以你会有类似的东西:
...
<xs:complexType>
<xs:attribute name="amount" type="xs:unsignedByte" />
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="initials" type="xs:string" />
</xs:complexType>
...
此外,如果你想拥有你的表格(所以<a att1 ="" /> <a att2="" />
)
你需要像这样改变你的属性:
<SETTINGS Version="1">
<A amount="40" />
<B name="abcd" />
<C initials="ABCD"/>
<D state="on" />
<E temperature="F"/>
</SETTINGS>
但我认为最后一种可能性可能比第一种选择有点过分
【讨论】:
Charles 是正确的,XSD 规定了CLEANING 的每个元素,可以有多个(maxOccurs=unbounded)需要所有的属性。您将不得不更改 XML 或 XSD 以使它们一起验证。是的,XSD 本身是有效的,XML 也是如此,但是 XML 不遵守此 XSD 设置的特定规则,只遵守一般 XML 规则。 我在这里有一个疑问@charles,<att a="" b="" c="" />
is different than <att a="" /> <att b="" /> <att c="" />
在第一种情况下,你在一个集团中拥有你所需要的一切。在另一边,你们都分裂了。事实是,如果您采用第二个选项(因此您删除了 require),您还可以编写 <att a="" /> <att b="" /> <att c="" />
或 <att a="" /> <att b="" c="" />
或 <att a="" b="" c="" />
或 <att a="" />
例如,我不认为你想要
@charles 我们有使用上述格式的 XML 的遗留代码,现在我们计划编写 XSD 来通过限制 XSD 文件中的属性值来验证 XML 中的模式和内容值。在这种情况下,由于某种原因无法更改 XML 格式。是否不可能编写具有属性值限制的 XSD 架构。根据您的建议,如果我们删除“use=required”,那么它可能会起作用,但在这种情况下,即使 XML 不包含该属性,它也会导致 XML 的成功验证--->以上是关于XML 的 XSD 验证失败的主要内容,如果未能解决你的问题,请参考以下文章
XML 和 XSD 验证失败:元素同时具有“类型”属性和“匿名类型”子项