首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >元素序列的XSD中的复杂规则

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

Stack Overflow用户
提问于 2009-06-26 09:18:36
回答 2查看 2.5K关注 0票数 1

在我的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尝试了几种方法,但都不起作用。有什么想法可以让我试试吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-06-26 10:28:52

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

代码语言:javascript
复制
<?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>

XML Schema1.1将添加断言支持,但这对断言XPath应用的范围有一些限制-您需要将断言放在X1..X6的父元素上。

还要注意,Schematron规则可以嵌入在xs:annotation/xs:appinfo中的XML Schema中,您应该能够同时针对XML Schema和嵌入的Schematron规则进行验证。

在操作评论之后跟进

嵌入上述Schematron规则的XML Schema如下所示。这是一个定义可以包含X1..X6的元素测试的示例。

代码语言:javascript
复制
<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>

实例文档可能如下所示:

代码语言:javascript
复制
<?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>

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

票数 4
EN

Stack Overflow用户

发布于 2009-06-26 09:58:14

无论如何,这里尝试了一种解决方案,假设X6可以是终端项目,而"OverallSequence“是基本元素。

代码语言:javascript
复制
<xs:complexType name="OverallSequence">
  <xs:group  ref="firstItem" />
</xs:complexType>

<xs:group name="sixthChoice">
  <xs:choice>
    <xs:group  ref="secondItem" />
    <xs:group  ref="thirdItem" />
    <xs:group  ref="fourthItem" />
    <xs:group  ref="fifthItem" />
    <xs:group  ref="sixthItem" />
  </xs:choice>
</xs:group>

<xs:group name="sixthItem">
  <xs:sequence>
    <xs:element name="X6" type="xs:string" />
    <xs:group    ref="sixthChoice" minOccurs="0" >
  </xs:sequence>
</xs:group>

<xs:group name="fifthItem">
  <xs:sequence>
    <xs:element name="X5"  type="xs:string" />
    <xs:group    ref="sixthItem" />
  </xs:sequence>
</xs:group>

<xs:group name="fourthChoice">
  <xs:choice>
    <xs:group  ref="secondItem" />
    <xs:group  ref="thirdItem" />
    <xs:group  ref="fourthItem" />
  </xs:choice>
</xs:group>

<xs:group name="fourthItem" />
  <xs:sequence>
    <xs:element name="X4" type="xs:string" />
    <xs:group    ref="fourthChoice" minOccurs="0" >
    <xs:group    ref="fifthItem" />
  </xs:sequence>
</xs:group>

<xs:group name="thirdItem" />
  <xs:sequence>
    <xs:element name="X3" type="xs:string" />
    <xs:group    ref="fourthItem">
  </xs:sequence>
</xs:group>

<xs:group name="secondItem" />
  <xs:sequence>
    <xs:element name="X2" type="xs:string" />
    <xs:group    ref="thirdItem">
  </xs:sequence>
</xs:group>

<xs:group name="firstItem" />
  <xs:sequence>
    <xs:element name="X1" type="xs:string" />
    <xs:group    ref="secondItem">
  </xs:sequence>
</xs:group>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1048166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档