我想实现一种关系,其中" Rate"元素应仅存在于" ComponentInstId和" ComponentInstIdServ"不存在,反之亦然。我怎么能在下面的xsd代码中做到这一点?
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="Component">
<xs:complexType>
<xs:all>
<xs:element name="ComponentId" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ComponentInstId" nillable="true" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ComponentInstIdServ" nillable="true" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Rate" nillable="true" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:whiteSpace value="collapse"/>
<xs:minInclusive value="0"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
答案 0 :(得分:2)
为什么不等同于(ComponentId, (Rate | (ComponentInstId, ComponentInstIdServ?)?))
?
允许订单变化有多重要?儿童的顺序是否提供了有用的信息?如果没有,请修复序列,就像HTML要求head
在body
之前而不是之后。如果序列确实提供了信息,您可以将可能性相乘,或者重构XML。如果将ComponentId作为Component上的必需属性,以及ComponentInst上的Id和IdServ属性,那么Component的内容模型可以只是(Rate | ComponentInst)?
。
你说&#34;顺序并不重要。&#34;如果这意味着&#34;序列不传达任何信息&#34;,则以下形式的声明可确保您始终拥有组件的Id以及Rate信息或ComponentInst信息,或两者都没有。
<xs:element name="Component">
<xs:complexType>
<xs:choice minOccurs="0">
<xs:element name="Rate" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:whiteSpace value="collapse"/>
<xs:minInclusive value="0"/>
</xs:restriction>
</xs:simpleType>
</
<xs:element name="ComponentInst" nillable="true">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="Id" type="xs:int"/>
<xs:attribute name="IdServ" type="xs:nonNegativeInteger"/>
</
</
</
<xs:attribute name="Id" type="xs:int" use="required"/>
</
</
(未经测试,因为缺少完整的末端标签是建议的。)
如果&#34;序列并不重要&#34;你的意思是&#34;所有可能的信息序列都必须是有效的,然后你的内容模型需要更复杂,但它足够简单的正则表达式来解决。
[附录]由于Stack Overflow的一些读者显然无法解决这样的问题,但是,这里有一个允许元素A(思考:ComponentId),B(思考:速率),C(ComponentInstId)和D(ComponentInstIdServ)以任何顺序出现,其中A是必需的,其他是可选的,并且具有约束,即如果B既不发生C也不发生D.
首先,让我们以DTD或Relax NG紧凑语法的紧凑表示法写出所有可能序列的选择:
( (A, B?)
| (A, C?, D?)
| (A, D?, C?)
| (B?, A)
| (C?, A, D?)
| (C?, D, A)
| (D?, A, C?)
| (D?, C, A)
)
然而,由于“独特的粒子归因”,这个(或者更确切地说是它的XSD等效物)并不合法。 XSD规则,因此我们需要分解各种左手前缀,并且通常使表达式具有确定性。一个实例可以从A,B,C或D开始,因此首先我们为这些情况制作四个确定性表达式,然后我们可以将它们放在一个选择中。如果A是第一个:
( A, ( (B) | (C, D?) | (D, C?) )? )
如果B是第一个:
(B, A?)
如果C是第一个:
(C ( (A, D?) | (D, A) ) )
如果D是第一个:
(D ( (A, C?) | (C, A) ) )
或者,现在一起:
( ( A, ( (B) | (C, D?) | (D, C?) )? )
| (B, A?)
| (C ( (A, D?) | (D, A) ) )
| (D ( (A, C?) | (C, A) ) )
)
或者,在XSD等价物中:
<xs:complexType name="demo">
<xs:choice>
<!--* we can start with A *-->
<xs:sequence>
<xs:element ref="A"/>
<xs:choice minOccurs="0">
<xs:element ref="B" minOccurs="0"/>
<xs:sequence>
<xs:element ref="C"/>
<xs:element ref="D" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="D"/>
<xs:element ref="C" minOccurs="0"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
<!--* or we can start with B *-->
<xs:sequence>
<xs:element ref="B"/>
<xs:element ref="A" minOccurs="0"/>
</xs:sequence>
<!--* or we can start with C *-->
<xs:sequence>
<xs:element ref="C"/>
<xs:choice>
<xs:sequence>
<xs:element ref="A"/>
<xs:element ref="D" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="D"/>
<xs:element ref="A"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
<!--* or we can start with D *-->
<xs:sequence>
<xs:element ref="D"/>
<xs:choice>
<xs:sequence>
<xs:element ref="A"/>
<xs:element ref="C" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="C"/>
<xs:element ref="A"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:choice>
</xs:complexType>