2013-01-14 20 views
3

這與How to create a schema for an unordered list of XML nodes, with occurrence constraints類似,但實際上稍微簡單一些。然而,我很難理解序列和選擇背後的邏輯(特別是當它們嵌套在序列選擇或序列選擇中時),儘管我已經研究了很長時間,但我不明白上面的例子作品。如何爲無序列表制定一個模式,其中一些發生一次,有時多次

我需要的是一個節點列表ChildA和ChildB,其中ChildA可以出現0-n次,但ChildB只有0-1次。 (其實我需要每種類型的幾個節點,但是如果我可以爲ChildA和ChildB做它,將它擴展到ChildX等和ChildY等應該很簡單)。應該沒有訂單限制。我會很感激任何幫助。任何深入解釋模式指標的鏈接也會有所幫助。

回答

4

這將是我腦海中浮現出最簡單的解決方案。這裏的關鍵點是在「主」序列中使用另一個序列。通過將內部序列設置爲<ChildB>開始並且<ChildB>通過將該序列的基數設置爲0-1而保持可選,該模式保持確定性。

這是一個XMLSchema 1.0解決方案。

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <!-- Schema for elements ChildA and ChildB 
     The requirements are as follows: 
      * ChildA and ChildB may occur in any order. 
      * ChildA is optional and may occur multiple times. 
      * ChildB is optional and may occur once only. 
    --> 

    <xs:element name="root"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element maxOccurs="unbounded" name="AB-container" type="AB-type" /> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 

    <xs:complexType name="AB-type"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" /> 
     <xs:sequence minOccurs="0"> 
     <xs:element name="ChildB" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="ChildA" type="xs:string" /> 
     </xs:sequence> 
    </xs:sequence> 
    </xs:complexType> 

</xs:schema> 
+0

Jasso。很多道歉,我應該爲此感謝你。我不得不繼續執行更高優先級的任務。我仍然沒有機會正確看待它,但我會按照答案打勾,因爲已經決定我們並不太擔心訂單限制,所以我可能永遠沒有機會真正地去掌握它。抱歉。 – Dave

1

簡而言之,它不能在XSD 1.0中完成;在XSD 1.1中,您可以使用xsd:all合成器(因爲只有maxOccurs = 1的XSD 1.0的限制已被刪除) - 但是,XSD 1.1的問題是:i)它只能作爲beta Xerces版本自由使用 - 與據我所知,在這個時候; ii)有一個SAXON版本支持它,上次我看到它的引用時,您將不得不爲此付費,並且iii)您將很難與其他人進行互操作,因爲其中大多數仍在XSD 1.0上。

如果您可以使用Schematron - 由於它只是XSLT 1.0/2.0,所以它比XSD 1.1更易於訪問,那麼應該很容易對它進行編碼,使得特定元素粒子的數量符合指定的標準;它會增加一個XSD,其中合成器將是重複的xsd:choice,其中選項選項是來自允許的集合中的元素。

有些人試圖通過使用正則表達式的結構來解釋XSD合成器。如果您熟悉這一點,那麼XSD 1.0中的xsd:all類似於方括號(雖然簡單得多,但沒有範圍或否定的概念),xsd:choice就像| (管道,交替)和xsd:sequence是其餘的(它在哪裏寫你的東西順序)。

我看到SO上的其他人推薦W3Schools。我沒有自己嘗試,因此我將這個免責聲明傳遞給你。

+0

這是一個恥辱。根據我引用的線程:「通過組合和嵌套由XML Schema提供的各種組,並設置minOccurs和maxOccurs的值,可以表示任何可用XML 1.0表示的內容模型。」我希望Jasso能夠提供解決更復雜問題的方法。我會繼續嘗試。 – Dave

0

@Dave正在爲ChildB添加一些愚蠢的屬性好嗎?由於您對childB的要求是0-1,我們可以通過向childB添加一個固定屬性並對屬性強制實施唯一約束來實現所需的解決方案。

<complexType name="childAType"> 
<simpleContent> 
    <extension base="string"></extension> 
</simpleContent> 
</complexType> 


<complexType name="childBType"> 
<simpleContent> 
    <extension base="string"> 
    <attribute name="value" type="string" fixed="123"></attribute> 
    </extension> 
</simpleContent> 
</complexType> 


<element name="root"> 
<complexType> 
    <choice minOccurs="0" maxOccurs="unbounded"> 
     <element name="childA" type="tns:childAType" minOccurs="0" maxOccurs="unbounded"></element> 
     <element name="childB" type="tns:childBType" minOccurs="0" maxOccurs="unbounded"></element> 
    </choice> 
</complexType> 
<unique name="childB.max.once"> 
    <selector xpath="./tns:childB"></selector> 
    <field xpath="@value"></field> 
</unique> 
</element> 

下面是有效的XML(B的順序無關緊要或B可以被排除)

<tns:root xmlns:tns=" "> 
<tns:childA></tns:childA> 
<tns:childB></tns:childB> 
<tns:childA></tns:childA> 
<tns:childA></tns:childA> 
</tns:root> 

之一。然而下面的一個是無效

<tns:root xmlns:tns=" "> 
<tns:childB></tns:childB> 
<tns:childA></tns:childA> 
<tns:childB></tns:childB> 
<tns:childA></tns:childA> 
<tns:childA></tns:childA> 
</tns:root> 
+0

對不起,延遲和謝謝嘗試,但如果我正確理解這個ChildB節點將有一個有效的「價值」屬性,我不想要的,所以它不是很理想。我會繼續嘗試。 – Dave

+0

@Dave XML實例不需要具有該屬性,它只駐留在xml模式中。我也想不出其他解決方案。 – Baski

+0

嗯。 XML * need *不具有該屬性,但是如果它確實可以正確驗證的話,這有點麻煩。還是我仍然誤解? – Dave

相關問題