Xsd assert在xerces验证中总是失败,但在xmlspy中工作

Xsd assert在xerces验证中总是失败,但在xmlspy中工作,xsd,xsd-validation,xerces,xpath-2.0,xsd-1.1,Xsd,Xsd Validation,Xerces,Xpath 2.0,Xsd 1.1,我正在为xml输入/输出设置模式,遇到了一个问题,XMLSpy验证ok,但Xerces在其中一个xs:断言上失败。 我使用的是最新的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.

我正在为xml输入/输出设置模式,遇到了一个问题,XMLSpy验证ok,但Xerces在其中一个xs:断言上失败。 我使用的是最新的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断言:架构类型“#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>


在XMLSpy中,如果我将SchemaVersion设置为2.0,断言将失败。如果将其设置为2.1,则断言成功。注意,这里可能有一些输入错误:断言需要XSD1.1,而不是XSD1.0;目前没有XSD2.0或2.1。有关如何使用Xerces根据XSD1.1验证XML的信息,请参见重复链接。请注意,“SchemaVersion”属性与XSD无关。它是xml的私有属性。我已经阅读了引用的问题,但它并不相同,因为其中一个在xsd 1.1上有问题,而我的问题处理xsd 1.1-但是xerces没有处理更复杂的断言语句。模式工厂被告知使用xsd 1.1,但没有。它理解断言,但似乎没有正确评估。对不起,我误解了你的问题。我已经重新打开了。那么,您是说来自根目录的“/”搜索不应该在断言中工作?还要注意,向上移动断言-意味着它没有要检查的ContentPositionRule属性,因此断言总是成功的。这也是一个极其简化的示例,在实际模式中,元素出现在层次结构中的几个不同位置。这意味着我需要为每个可能的路径添加另一个断言副本。这使得断言远没有那么有用。不,我是说断言不应该试图引用关联元素的兄弟节点或祖先节点。您可以通过
/
相对地访问后代,但是,如果我正确理解您的目标,这应该不会像您担心的那样令人望而却步。只是花了一些时间尝试变体。在顶级元素中时,这似乎起作用。。。因此,几乎所有的元素间验证都需要在顶级元素中进行。可维护性不是特别好。说话太早了。我似乎找不到一种语法变体,允许我将ContentPositionRule的检查仅限于顶部元素下的“Page”元素。