xs:assert xerces 验证总是失败,但在 xmlspy 中有效

xs:assert always fails with xerces validation, but works in xmlspy

我正在为我们的 xml input/output 设置架构,运行 遇到一个问题,XMLSpy 验证正常,但 Xerces 在 [=39= 之一上失败]. 我正在使用最新的 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: Assertion evaluation ('(//@SchemaVersion ge 2.1) or ((//@SchemaVersion lt 2.1) and not (@ContentPositionRule))') for element 'Page' 模式类型“#AnonType_Page”未成功。

在 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>

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

另请参阅:

XMLSpy 的观察行为

尽管在技术上(尽管没有帮助)不为出现断言的元素的兄弟姐妹或祖先元素的断言提供诊断帮助,但 XMLSpy 不应根据兄弟姐妹或祖先状态报告不同的验证结果。

W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures

Validation Rule: Assertion Satisfied

[...]

1.3 From the "partial" ·post-schema-validation infoset·, a data model instance is constructed as described in [XDM]. The root node of the [XDM] instance is constructed from E; the data model instance contains only that node and nodes constructed from the [attributes], [children], and descendants of E. Note: It is a consequence of this construction that attempts to refer, in an assertion, to the siblings or ancestors of E, or to any part of the input document outside of E itself, will be unsuccessful. Such attempted references are not in themselves errors, but the data model instance used to evaluate them does not include any representation of any parts of the document outside of E, so they cannot be referred to.

Note: It is a consequence of this construction that attempts to refer, in an assertion, to the siblings or ancestors of E, or to any part of the input document outside of E itself, will be unsuccessful. Such attempted references are not in themselves errors, but the data model instance used to evaluate them does not include any representation of any parts of the document outside of E, so they cannot be referred to.

[强调 添加。]