我正在尝试使用XSD 1.1创建模式定义,其中其他元素的数量取决于另一个元素的属性。 例如。 BaPath元素BaPath的数量取决于“Conn”元素的属性“service”的值。 我写的xsd是
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Mapping">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Link" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Env">
<xsd:complexType>
<xsd:attribute name="name" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="UTEST" />
<xsd:enumeration value="TEST" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="Link">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Conn" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="service" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="FILESNF" />
<xsd:enumeration value="MSGSNF" />
<xsd:enumeration value="MSGRT" />
<xsd:enumeration value="FILERT" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="Conn">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="BaPath" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="BaPath">
<xsd:complexType>
<xsd:attribute name="flow" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:assertion test="@service eq 'MSGRT'">
<xsd:enumeration value="TRS" />
<xsd:enumeration value="ZTRS" />
</xsd:assertion>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="Dep">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Env" maxOccurs="unbounded" />
<xsd:element ref="Mapping" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="CfgType">
<xsd:sequence>
<xsd:element ref="Dep" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Cfg" type="CfgType"></xsd:element>
</xsd:schema>
</Cfg>
例如,如果Conn元素具有属性服务eq'MSGRT',则必须有2个具有TRS和ZTRS属性的BaPath元素
<Cfg xmlns="http://www.alpha.com/beta">
<Dep>
<Env name="UTEST"/>
<Mapping>
<Link t2s_service="MSGRT">
<Conn>
<BaPath flow="ZTRS"/>
<BaPath flow="TRS"/>
</Conn>
</Link>
</Mapping>
</Dep>
如果conn的服务eq'FILESNF'必须有3个带有属性FTS,ZFTS和MSSDN的BaPath元素
我尝试了不同的解决方案,但似乎没有人工作。是否有可能通过断言xsd-1.1来解决这个问题?
答案 0 :(得分:3)
您可以在链接元素中使用断言 (以及包含流中所有值的枚举属性)。
<xsd:element name="Link">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Conn" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="service" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="FILESNF"/>
<xsd:enumeration value="MSGSNF"/>
<xsd:enumeration value="MSGRT"/>
<xsd:enumeration value="FILERT"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:assert test="(@service ne 'MSGRT') or (count(Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2]) eq count(Conn))"></xsd:assert>
<xsd:assert test="(@service ne 'FILESNF') or (count(Conn[count(BaPath[@flow eq 'FTS']) eq 1 and count(BaPath[@flow eq 'MSSDN']) eq 1 and count(BaPath[@flow eq 'ZFTS']) eq 1 and count(BaPath) eq 3]) eq count(Conn))"></xsd:assert>
</xsd:complexType>
</xsd:element>
其中一个断言的解释(其他断言类似):
(@service ne 'MSGRT') or (count(Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2]) eq count(Conn))
首先,我们检查服务属性。
然后,使用Conn[count(BaPath[@flow eq 'TRS']) eq 1 and count(BaPath[@flow eq 'ZTRS']) eq 1 and count(BaPath) eq 2]
我们选择链接的所有 Conn 元素,它们只有两个 BaPath 子元素(一个带有flow = TRS和其他与flow = ZTRS)。
之后,我们检查所有Conn元素是否通过了该限制。
所以,使用它,这个例子是有效的:
<Link service="MSGRT">
<Conn>
<BaPath flow="TRS"></BaPath>
<BaPath flow="ZTRS"></BaPath>
</Conn>
</Link>
此示例无效:
<Link service="MSGRT">
<Conn>
<BaPath flow="MSSDN"></BaPath>
<BaPath flow="ZTRS"></BaPath>
</Conn>
</Link>
此示例无效:
<Link service="MSGRT">
<Conn>
<BaPath flow="TRS"></BaPath>
</Conn>
</Link>
此示例无效:
<Link service="MSGRT">
<Conn>
<BaPath flow="TRS"></BaPath>
<BaPath flow="ZTRS"></BaPath>
<BaPath flow="ZFTS"></BaPath>
</Conn>
</Link>
编辑:
使用conditional type alternatives
(示例here)的另一个选择,但您可能需要复制模式的部分内容。