在我的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尝试了几种方法,但都不起作用。有什么想法可以让我试试吗?
发布于 2009-06-26 10:28:52
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>XML Schema1.1将添加断言支持,但这对断言XPath应用的范围有一些限制-您需要将断言放在X1..X6的父元素上。
还要注意,Schematron规则可以嵌入在xs:annotation/xs:appinfo中的XML Schema中,您应该能够同时针对XML Schema和嵌入的Schematron规则进行验证。
在操作评论之后跟进
嵌入上述Schematron规则的XML Schema如下所示。这是一个定义可以包含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>使用oXygen XML编辑器对上述内容进行了测试。该实例还将XML Schema与处理指令相关联,以告诉oXygen该模式包含嵌入的Schematron规则。验证是根据XML Schema和Schematron规则执行的。
发布于 2009-06-26 09:58:14
无论如何,这里尝试了一种解决方案,假设X6可以是终端项目,而"OverallSequence“是基本元素。
<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>https://stackoverflow.com/questions/1048166
复制相似问题