2012-08-16 64 views
0

我想创建一个模式文件2个不同的XML的(我可以把它分成2种模式,但由于根元素是一样的,我希望把它放在一个文件)。创建2种不同类型相同的根元素

现在我有2分不同的XML的。

<orderStatus shipStatus="SHIPPED/PENDING"> 
    <orderId>1234</orderId> 
    <orderedBy>userName</orderedBy> 
    <orderedOn>2012-07-23T11:35:51.000-04:00</orderedOn> 
</orderStatus> 

和第二XML是

<orderStatus modifyShipStatus="SUSPENDED/PENDING"> 
    <shipStatus>101</shipStatus> 
</orderStatus> 

如何可以有1个XSD这些2个XML?当我试图创建一个1类型的根元素,它工作正常,但是当我尝试添加另一种类型时,JAXB抛出错误,该元素已被定义。这使得sens。

回答

2

答案在很大程度上取决于你想说什么部分,一部分对您所使用的模式语言:DTD的? XSD 1.0? XSD 1.1? RelaxNG?其他......?哦,对,我发现问题是标记为XSD,所以我假设你正在寻找一个XSD解决方案。

如果你想说的orderStatus元素可以有要么序列orderIdorderedBy,或orderedOn儿童序列shipStatus,而且属性shipStatusmodifyShipStatus是可选的,那么在这样说内容模型很简单。

在DTD符号(我在这里使用了它的紧凑性),你可以这样写:

<!ELEMENT orderStatus ((orderId, orderedBy, orderedOn) | shipStatus) > 
<!ATTLIST orderStatus 
      shipStatus CDATA #IMPLIED 
      modifyShipStatus CDATA #IMPLIED 
> 

还是在XSD符号,写

<xs:element name="orderStatus" type="my:orderStatus"/> 
<xs:complexType name="orderStatus"> 
    <xs:choice> 
    <xs:sequence> 
     <xs:element ref="my:orderId"/> 
     <xs:element ref="my:orderedBy"/> 
     <xs:element ref="my:orderedOn"/> 
    </xs:sequence> 
    <xs:element ref="my:shipStatus"/> 
    </xs:choice> 
    <xs:attribute name="shipStatus"/> 
    <xs:attribute name="modifyShipStatus"/> 
</xs:complexType> 

然后你就大功告成了。

如果你想只允许两个属性中的一个,或者如果你想合法子女依赖于一个或另一个属性是否存在,事情更复杂。 (有些文档设计人员会说,如果你需要,你有两种截然不同的元素类型,你坚持用相同的名字来调用,这使得验证变得毫无困难。)

在这种情况下,你的选择是:

  • 使用DTD和/或XSD架构1.0如上所述,并表达附加约束的文档中,或者使用Schematron的,或通过一些其它方法。

  • 使用XSD 1.1,定义内容模型和如上所述的属性,并添加断言说属性shipStatus

    • 恰好一个和modifyShipStatus必须出现。当且仅当出现一个名为orderId孩子
    • 属性shipStatus必须出现。当且仅当出现一个名为shipStatus孩子
    • 属性modifyShipStatus必须出现。
  • 使用XSD 1。1,定义了两种不同类型的两种格式orderStatus元素和使用条件类型分配说适用的类型时:

的XSD将是这个样子:

<xs:complexType name="orderStatus1"> 
     <xs:sequence> 
     <xs:element ref="my:orderId"/> 
     <xs:element ref="my:orderedBy"/> 
     <xs:element ref="my:orderedOn"/> 
     </xs:sequence> 
     <xs:attribute name="shipStatus"/> 
    </xs:complexType> 
    <xs:complexType name="orderStatus2"> 
     <xs:element ref="my:shipStatus"/> 
     <xs:attribute name="modifyShipStatus"/> 
    </xs:complexType> 

    <xs:element name="orderStatus"> 
     <xs:alternative test="@shipStatus" type="my:orderStatus1"/> 
     <xs:alternative test="@modifyShipStatus" type="my:orderStatus2"/> 
    </xs:element> 
  • 我我们会顺便注意到,它的爱好者经常引用Relax NG的能力来制定这种限制作为其优势之一。
相关问题