Xpath结果与xs:断言结果

时间:2015-03-19 17:21:58

标签: xml xpath xsd

我使用oXygen XML Editor 16.1使用SaxonEE set for XML Schema 1.1进行这些测试。

我想确保复杂类型中的元素是基本complexType的限制,具有相同数量的枚举。 (以下代码)

示例complexType(帖子的底部)应该使此断言失败:

<xs:assert test="count(//xs:element[@name='id-name']//xs:enumeration)  
eq count(//xs:element[@name='issuer']//xs:enumeration) 
and
count(//xs:element[@name='issuer']//xs:enumeration) 
eq count(//xs:element[@name='assignor']//xs:enumeration)"></xs:assert>

因为赋值器有三个枚举而其他元素有两个。无论我将它放在基本complexType还是受限制的complexType中,它仍然将限制显示为有效模式。

如果我执行此

count(//xs:element[@name='id-name']//xs:enumeration) 
  eq count(//xs:element[@name='issuer']//xs:enumeration) and
count(//xs:element[@name='issuer']//xs:enumeration) 
  eq count(//xs:element[@name='assignor']//xs:enumeration)

在XPath编辑器中,它失败(返回false),并且当三个都有两个枚举时传递(返回true)。

样本限制:

 <xs:complexType name='mytype' xml:lang='en-US'>
<xs:complexContent>
  <xs:restriction base='myBaseType'>
    <xs:sequence>
        <xs:element maxOccurs='1' minOccurs='1' name='id-name'>
          <xs:simpleType>
            <xs:restriction base='xs:string'>
              <xs:enumeration value='URI'></xs:enumeration>
              <xs:enumeration value='ID Number'></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element maxOccurs='1' minOccurs='1' name='issuer'>
          <xs:simpleType>
            <xs:restriction base='xs:string'>
              <xs:enumeration value='Owner'/>
              <xs:enumeration value='Owner'/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element maxOccurs='1' minOccurs='1' name='assignor'>
          <xs:simpleType>
            <xs:restriction base='xs:string'>
              <xs:enumeration value='Owner'/>
              <xs:enumeration value='Owner'/>
              <xs:enumeration value='Owner'/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:sequence>
    </xs:restriction>
  </xs:complexContent>
    </xs:complexType>

&#39; myBaseType&#39;在另一个包含的模式中#39;在这一个。复杂类型如下所示:

  <xs:complexType name="myBaseType">
<xs:complexContent>
  <xs:extension base="someType">
    <xs:sequence>
      <xs:element maxOccurs="1" minOccurs="0" name="id-name" type="xs:string"></xs:element>
      <xs:element maxOccurs="1" minOccurs="0" name="issuer" type="xs:string"></xs:element>
      <xs:element maxOccurs="1" minOccurs="0" name="assignor" type="xs:string"></xs:element>
    </xs:sequence>
    <xs:assert test="count(//xs:element[@name='id-name']//xs:enumeration) eq count(//xs:element[@name='issuer']//xs:enumeration) and
      count(//xs:element[@name='issuer']//xs:enumeration) eq count(//xs:element[@name='assignor']//xs:enumeration)
      "></xs:assert>
  </xs:extension>
</xs:complexContent>

我错过了什么?我不能在限制complexType上建立断言,或者仅对断言进行实例数据的评估吗?在我看来,因为&#39; mytype&#39;是对myBaseType&#39;的限制然后应该应用断言。

1 个答案:

答案 0 :(得分:2)

正如您在问题结束时预期的那样,断言的范围是由XSD管理的XML文档实例,而不是XSD本身。如果您希望对XSD本身进行断言,则必须创建一个将原始XSD视为XML文档的meta-xsd。

您可以从XML Schema schema开始。但是,您应该考虑使用Schematron断言,这可能更适合选择性地执行约束。我已经使用Schematron而不是XSD来执行组织惯例,并发现它是检查所采用政策合规性的可行方法。


每个OP评论更新

  

&#39; 如果您想对XSD本身做出断言,那么您必须   创建一个meta-xsd,将原始XSD视为XML文档&#39; -   是的,这就是我所做的。

不,那不是你做过的。您正在尝试从验证XML文档实例的同一XSD对XSD进行断言。它是通过xsd:include引入的单独XSD的事实没有改变;它仍然只是域XSD,而不是域XSD的元XSD。我所说的是你必须有一个元XSD,这意味着一个单独的XSD验证你的域XSD。你已经低估了这项任务所涉及的复杂性。如果您没有从XML Schema架构开始,那么您就没有意识到meta XSD必须做什么。

  

如果可以使用XSD,我真的不想使用schematron   1.1然后为什么要添加另一个复杂因素?

因为通过Schematron或其他技术强制执行点约束的复杂性实际上比通过XSD验证所有XSD的复杂性更低,然后加上一些断言来覆盖点约束。此外,XSD 1.1的断言设施比Schematron的断言要严格得多。