Xml XSD中元素序列的复杂规则

Xml XSD中元素序列的复杂规则,xml,xsd,Xml,Xsd,在我的XML中有6个元素X1、X2、X3、X4、X5和X6。规则如下— X1后面必须跟X2 X2后面必须跟X3 X3后面必须跟X4 X4后面必须跟X2、X3、X4或X5 X5后面必须跟X6 X6后面可以是X2、X3、X4、X5或X6 我正试图为此定义一个XSD。可能吗?我尝试了一些使用sequence、minOccur和maxOccur的方法,但没有成功。有什么想法我可以试试吗?无论如何,这里有一个解决方案,假设X6可以是终端项,而整体序列是基本元素 无论如何,这里有一个解决方案,假设X6可以是

在我的XML中有6个元素X1、X2、X3、X4、X5和X6。规则如下—

X1后面必须跟X2

X2后面必须跟X3

X3后面必须跟X4

X4后面必须跟X2、X3、X4或X5

X5后面必须跟X6

X6后面可以是X2、X3、X4、X5或X6


我正试图为此定义一个XSD。可能吗?我尝试了一些使用sequence、minOccur和maxOccur的方法,但没有成功。有什么想法我可以试试吗?

无论如何,这里有一个解决方案,假设X6可以是终端项,而整体序列是基本元素


无论如何,这里有一个解决方案,假设X6可以是终端项,而整体序列是基本元素


XML Schema 1.0无法处理这种情况。 另一方面,Schematron直接转换您的约束,请参见下面的工作/测试Schematron模式:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
  <pattern>
    <rule context="X1">
      <assert test="following-sibling::*[1][self::X2]">
        X1 must be followed by X2
      </assert>
    </rule>
    <rule context="X2">
      <assert test="following-sibling::*[1][self::X3]">
        X2 must be followed by X3
      </assert>
    </rule>
    <rule context="X3">
      <assert test="following-sibling::*[1][self::X4]">
        X3 must be followed by X4
      </assert>
    </rule>
    <rule context="X4">
      <assert test="following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5]">
        X4 must be followed by X2, X3, X4 or X5
      </assert>
    </rule>
    <rule context="X5">
      <assert test="following-sibling::*[1][self::X6]">
        X5 must be followed by X6
      </assert>
    </rule>
    <rule context="X6">
      <assert test="not(following-sibling::*) or following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5 or self::X6]">
        X6 can be followed by X2, X3, X4, X5 or X6
      </assert>
    </rule>
  </pattern>
</schema>
XMLSchema1.1将添加断言支持,但这对断言XPath应用的范围有一些限制-您需要将断言放在X1..X6的父元素上

还要注意,Schematron规则可以嵌入xs:annotation/xs:appinfo中的XML模式中,您应该能够根据XML模式和嵌入的Schematron规则进行验证

在OP评论之后跟进 下面是嵌入上述Schematron规则的XML模式。这是一个定义元素测试的示例,该测试可以包含X1..X6

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:sch="http://purl.oclc.org/dsdl/schematron">
  <xs:annotation>
    <xs:appinfo>
      <sch:title>Sample embedded Schematron rules</sch:title>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="test">
    <xs:annotation>
      <xs:appinfo>
        <sch:pattern>
          <sch:rule context="X1">
            <sch:assert test="following-sibling::*[1][self::X2]"> X1 must be followed by X2 </sch:assert>
          </sch:rule>
          <sch:rule context="X2">
            <sch:assert test="following-sibling::*[1][self::X3]"> X2 must be followed by X3 </sch:assert>
          </sch:rule>
          <sch:rule context="X3">
            <sch:assert test="following-sibling::*[1][self::X4]"> X3 must be followed by X4 </sch:assert>
          </sch:rule>
          <sch:rule context="X4">
            <sch:assert test="following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5]"> X4
              must be followed by X2, X3, X4 or X5 </sch:assert>
          </sch:rule>
          <sch:rule context="X5">
            <sch:assert test="following-sibling::*[1][self::X6]"> X5 must be followed by X6 </sch:assert>
          </sch:rule>
          <sch:rule context="X6">
            <sch:assert
              test="not(following-sibling::*) or following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5 or self::X6]"
              > X6 can be followed by X2, X3, X4, X5 or X6 </sch:assert>
          </sch:rule>
        </sch:pattern>
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element ref="X1"/>
        <xs:element ref="X2"/>
        <xs:element ref="X3"/>
        <xs:element ref="X4"/>
        <xs:element ref="X5"/>
        <xs:element ref="X6"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name="X1"/>
  <xs:element name="X2"/>
  <xs:element name="X3"/>
  <xs:element name="X4"/>
  <xs:element name="X5"/>
  <xs:element name="X6"/>
</xs:schema>
实例文档可以如下所示:

<?oxygen SCHSchema="test.xsd"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="test.xsd">
  <X1/>
  <X2/>
  <X3/>
  <X4/>
  <X4/>
  <X3/>
  <X4/>
  <X5/>
  <X6/>
  <X4/>
  <X5/>
  <X6/>
</test>

以上是用OxygenXML编辑器测试的。该实例还将XML模式与处理指令相关联,以告诉oXygen该模式包含嵌入式Schematron规则。验证同时针对XML模式和Schematron规则执行。

XML模式1.0无法处理这种情况。 另一方面,Schematron直接转换您的约束,请参见下面的工作/测试Schematron模式:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
  <pattern>
    <rule context="X1">
      <assert test="following-sibling::*[1][self::X2]">
        X1 must be followed by X2
      </assert>
    </rule>
    <rule context="X2">
      <assert test="following-sibling::*[1][self::X3]">
        X2 must be followed by X3
      </assert>
    </rule>
    <rule context="X3">
      <assert test="following-sibling::*[1][self::X4]">
        X3 must be followed by X4
      </assert>
    </rule>
    <rule context="X4">
      <assert test="following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5]">
        X4 must be followed by X2, X3, X4 or X5
      </assert>
    </rule>
    <rule context="X5">
      <assert test="following-sibling::*[1][self::X6]">
        X5 must be followed by X6
      </assert>
    </rule>
    <rule context="X6">
      <assert test="not(following-sibling::*) or following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5 or self::X6]">
        X6 can be followed by X2, X3, X4, X5 or X6
      </assert>
    </rule>
  </pattern>
</schema>
XMLSchema1.1将添加断言支持,但这对断言XPath应用的范围有一些限制-您需要将断言放在X1..X6的父元素上

还要注意,Schematron规则可以嵌入xs:annotation/xs:appinfo中的XML模式中,您应该能够根据XML模式和嵌入的Schematron规则进行验证

在OP评论之后跟进 下面是嵌入上述Schematron规则的XML模式。这是一个定义元素测试的示例,该测试可以包含X1..X6

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:sch="http://purl.oclc.org/dsdl/schematron">
  <xs:annotation>
    <xs:appinfo>
      <sch:title>Sample embedded Schematron rules</sch:title>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="test">
    <xs:annotation>
      <xs:appinfo>
        <sch:pattern>
          <sch:rule context="X1">
            <sch:assert test="following-sibling::*[1][self::X2]"> X1 must be followed by X2 </sch:assert>
          </sch:rule>
          <sch:rule context="X2">
            <sch:assert test="following-sibling::*[1][self::X3]"> X2 must be followed by X3 </sch:assert>
          </sch:rule>
          <sch:rule context="X3">
            <sch:assert test="following-sibling::*[1][self::X4]"> X3 must be followed by X4 </sch:assert>
          </sch:rule>
          <sch:rule context="X4">
            <sch:assert test="following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5]"> X4
              must be followed by X2, X3, X4 or X5 </sch:assert>
          </sch:rule>
          <sch:rule context="X5">
            <sch:assert test="following-sibling::*[1][self::X6]"> X5 must be followed by X6 </sch:assert>
          </sch:rule>
          <sch:rule context="X6">
            <sch:assert
              test="not(following-sibling::*) or following-sibling::*[1][self::X2 or self::X3 or self::X4 or self::X5 or self::X6]"
              > X6 can be followed by X2, X3, X4, X5 or X6 </sch:assert>
          </sch:rule>
        </sch:pattern>
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element ref="X1"/>
        <xs:element ref="X2"/>
        <xs:element ref="X3"/>
        <xs:element ref="X4"/>
        <xs:element ref="X5"/>
        <xs:element ref="X6"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name="X1"/>
  <xs:element name="X2"/>
  <xs:element name="X3"/>
  <xs:element name="X4"/>
  <xs:element name="X5"/>
  <xs:element name="X6"/>
</xs:schema>
实例文档可以如下所示:

<?oxygen SCHSchema="test.xsd"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="test.xsd">
  <X1/>
  <X2/>
  <X3/>
  <X4/>
  <X4/>
  <X3/>
  <X4/>
  <X5/>
  <X6/>
  <X4/>
  <X5/>
  <X6/>
</test>

以上是用OxygenXML编辑器测试的。该实例还将XML模式与处理指令相关联,以告诉oXygen该模式包含嵌入式Schematron规则。验证是针对XML模式和Schematron规则执行的。

需要澄清的是,当X4后面跟X3时,X3的前一条规则仍然适用,对吗?e、 g.X1、X2、X3、X4、X3、X4、X3、X4、X5、X6。如果是这样的话,那么似乎存在一个问题,XML文档永远不会结束。或者X6可以作为最后一项吗?除了文档的小问题“永无止境”之外,序列可以从什么开始?xml可以仅从X1开始,也可以仅从X6结束。需要明确的是,当X4后面跟着X3时,X3的先前规则仍然适用,对吗?e、 g.X1、X2、X3、X4、X3、X4、X3、X4、X5、X6。如果是这样的话,那么似乎存在一个问题,XML文档永远不会结束。或者X6可以作为最后一项?除了文档的小问题“永无止境”之外,序列可以从什么开始?xml只能从X1开始,只能从X6结束。这不起作用,它抱怨循环引用。正如你们所看到的,第四项包括第四项选择,第四项选择也包括第四项选择。其他人也是如此。这是行不通的,它抱怨循环引用。正如你们所看到的,第四项包括第四项选择,第四项选择也包括第四项选择。其他人也是如此。在我当前的xsd中,在哪里添加此模式?我在我的架构下添加了模式元素并定义了xml名称空间,但它给出了错误或缺少根元素。有关完整的工作示例,请参阅我回答中的后续内容。在我当前的xsd中在何处添加此模式?我在我的模式下添加了模式元素并定义了xml名称空间,但它给出了错误或缺少根元素。有关完整的工作示例,请参阅我答案中的后续内容。