XS:Assert 总是在 Xerces 验证时失败,但在 XMLSPY 中工作



我正在为我们的xml输入/输出设置模式,并遇到了XMLSpy验证正常的问题,但Xerces在其中一个xs:asserts上失败。 我正在使用最新的xerces,xerces-2_12_0-xml-schema-1.1。

我已经包含了该发行版中的所有.jar文件(xercesSamples.jar除外(

测试代码为:

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
factory.setFeature("http://apache.org/xml/features/validation/cta-full-xpath-checking", true);
Schema schema = factory.newSchema(new File("C:/Imports/Test.xsd"));
validator = schema.newValidator();
validator.validate(new StreamSource("C:/Imports/Test.xml"));

我已经将 xsd 文件修剪为:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:lit="http://www.w3schools.com" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">
<xs:element name="MetrixXML">
<xs:complexType>
<xs:all>
<xs:element ref="lit:Page" minOccurs="1" maxOccurs="unbounded"/>
</xs:all>
<xs:attribute name="SchemaVersion" type="xs:float" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Page">
<xs:complexType>
<xs:attribute name="ContentPositionRule" type="xs:string"/>
<xs:attribute name="FilePageNum" type="xs:nonNegativeInteger"/>
<xs:assert test="(//@SchemaVersion ge 2.1) or ((//@SchemaVersion lt 2.1) and not (@ContentPositionRule))"/>
</xs:complexType>
</xs:element>
</xs:schema>

该 xml 是:

<?xml version="1.0" encoding="UTF-8"?>
<MetrixXML xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com Test.xsd" SchemaVersion="2.1" >
<Page FilePageNum="1"/>
<Page ContentPositionRule="CenterEachPage"/>
</MetrixXML>

我得到的错误是:

org.xml.sax.SAXParseException: cvc-assertion: 架构类型"#AnonType_Page"上的元素"Page"的断言评估('(//@SchemaVersion ge 2.1( 或 ((//@SchemaVersion lt 2.1( 而不是 (@ContentPositionRule(('('(未成功。

在 XMLSpy 中,如果我将 SchemaVersion 设置为 2.0,断言将失败。 如果我将其设置为 2.1,断言成功。

是否需要设置一些功能标志?

更新: 显然,XMLSpy允许它不应该允许的事情。

因此,所需的测试是 如果(SchemaVersion <2.1(并且任何元素包含"ContentPositionRule"属性,那么它应该失败。

将断言在层次结构中上移一级,并确保它仅引用关联元素的后代:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:lit="http://www.w3schools.com"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
targetNamespace="http://www.w3schools.com" 
elementFormDefault="qualified"
attributeFormDefault="unqualified" vc:minVersion="1.1">
<xs:element name="MetrixXML">
<xs:complexType>
<xs:all>
<xs:element ref="lit:Page" minOccurs="1" maxOccurs="unbounded"/>
</xs:all>
<xs:attribute name="SchemaVersion" type="xs:float" use="required"/>
<xs:assert test=" (@SchemaVersion ge 2.1) or 
((@SchemaVersion lt 2.1) and 
not (lit:Page/@ContentPositionRule))       
</xs:complexType>
</xs:element>
<xs:element name="Page">
<xs:complexType>
<xs:attribute name="ContentPositionRule" type="xs:string"/>
<xs:attribute name="FilePageNum" type="xs:nonNegativeInteger"/>
</xs:complexType>
</xs:element>
</xs:schema>

断言只允许引用它出现的元素和该元素的后代——而不是它的祖先、兄弟姐妹等。

另请参阅:

  • 如何在 XSD 断言 XPath 中访问父元素?

XMLSpy 观察到的行为

尽管从技术上讲(尽管没有帮助(不为出现断言的元素的同级或祖先的断言提供诊断帮助是一致的,但 XMLSpy 不应根据同级或祖先状态报告不同的验证结果。

W3C XML 架构定义语言 (XSD( 1.1 第 1 部分:结构

验证规则:满足断言

[...]

1.3 从"部分"的"后模式验证信息集·"中,按照[XDM]中所述构造数据模型实例。的根节点 [XDM] 实例由 E 构造;数据模型实例包含 只有该节点和从 [属性] 构造的节点, [孩子]和E的后代注:这是其结果 试图在断言中引用兄弟姐妹的结构 或 E 的祖先,或 E 之外的输入文档的任何部分 本身,将不成功。此类尝试的引用不在 本身错误,但用于评估它们的数据模型实例 不包括文档任何部分的任何表示形式 在 E 之外,因此不能引用它们。

注意:这是这种结构的结果,它试图在断言中引用 E 的兄弟姐妹或祖先,或任何 部分输入文档在 E 本身之外,将不成功。这种尝试的引用本身不是错误,而是数据 用于评估它们的模型实例不包括任何 表示文档在 E 之外的任何部分,因此它们 不能引用。

[着重号后加。

相关内容

最新更新