2012-09-18 50 views
0

我希望定義強制執行下列規則XSD(基於V1.0)...控制maxOccurs的嵌套元素,而不執行序列

我有一個parent1元件,其可具有以下子元件兒童1,兒童2兒童3

  • parent1可以具有parent1 0-1的child1
  • 可以具有0-1 的的child2
  • parent1可具有0 - 無界的child3

orde這些項目並不重要。例如。

<parent1> 
    <child3/> 
    <child1/> 
    <child2/> 
    <child3/> 
    <child3/> 
</parent1> 

我已經關閉了,但沒有雪茄。我能得到的最接近的是強制執行最小和最大值,但順序是強制執行的。

<xsd:element name="parent1" minOccurs="0" maxOccurs="unbounded"> 
    <xsd:complexType> 
    <xsd:sequence> 
     <xsd:element name="child1" minOccurs="0" maxOccurs="1"/> 
     <xsd:element name="child2" minOccurs="0" maxOccurs="1" /> 
     <xsd:element name="child3" minOccurs="0" maxOccurs="unbounded"/> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 

我一直在使用all代替sequence試過,但限制maxOccurs爲1的子元素。我也嘗試使用選項maxOccurs來替換序列,但這並不限制您可以在parent1之下有多少個child1child2元素。

編輯:這是XSD 1.0

我發現,對於XSD 1.1有效的解決方案,但是當你看到它是在Eclipse的喜歡如何很好的支持,我會努力並堅持與1.0

回答

0

要在XML Schema 1.0中執行此操作,您最終必須將「將」xs:all顆粒「展開」爲序列選擇樹(每個選項的每個分支都有唯一的非可選第一個元素)你是這樣的:

編輯:糾正了我對要求的看法,並大大減少了冗長。還進行了一些優化以進一步減少冗長:包含空分支的選項在選擇上將空分支轉換爲minOccurs=0,並且如果該轉換僅留下一個分支的選擇,則選擇本身被省略,並且minOccurs="0"轉移到它的唯一兒童。

<xs:sequence> 
    <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" /> 
    <xs:choice minOccurs="0"> 
    <xs:sequence> 
     <xs:element name="name" /> 
     <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" /> 
     <xs:sequence minOccurs="0"> 
     <xs:element name="email" /> 
     <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:sequence> 
    <xs:sequence> 
     <xs:element name="email"> 
     <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" /> 
     <xs:sequence minOccurs="0"> 
     <xs:element name="name" /> 
     <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:sequence> 
    </xs:choice> 
</xs:sequence> 
+0

謝謝你的答案。鑑於解決方案有多冗長,我們必須考慮使用v1.1。我的例子是一個相當小的人爲的例子,只是想了解1.0解決方案。實際上,我們將有超過3個子元素類型。而這只是XSD的1個區域。 – Roadkillnz

+0

@Roadkillnz現在我有了更多的腦細胞功能,我想出了一個更短的解決方案。儘管如此,它仍然很冗長。 –

0

正如Hantin所說,這在XSD 1.0中是組合式的混亂。

在XSD 1.1中,您可以在xs:all模型組的粒子上擁有maxOccurs屬性,以便解決您的問題。 XSD 1.1目前在Saxon和Xerces中實施。

+0

謝謝,很高興知道。我們面臨的問題是我們打算將Eclipse用作定義綁定到該XSD的XML的開發環境。 XML + XSD是大圖的一小部分。 Eclipse或Web Tools Platform仍然不支持1.1是令人遺憾的。也許有一個第三方插件可以來拯救我們。 – Roadkillnz

0

這並不特別困難,儘管邁克爾凱指出,這是混亂和令人失望的詳細。 (再次爲簡潔起見)翻譯傑弗裏Hantin的例子爲DTD記法簡潔和使用c1c2,並c3的元素名稱,該解決方案是

(c3*, ((c1, c3*, (c2, c3*)?) | (c2, c3*, (c1, c3*)?))?) 

如果子元素的順序傳遞信息,那麼它的重要當然,所有這些訂購的靈活性。如果序列沒有傳達任何信息,則不需要考慮靈活性,通常應該優先考慮OP的原始解決方案。

+0

Thankyou爲您翻譯關於我的示例的Hantin解決方案。 XSD 1.0錯過了我認爲是定義XML驗證規則的明顯用法,這似乎相當了不起。但是,再一次,成爲對某些事物的批評總是容易的 - 設計一些靈活的東西,並且覆蓋所有的案例可能是一個不同的故事。 – Roadkillnz

+0

我想這取決於你的意思是「錯過」。你說你想要的內容模型可以用XSD來表示,就像在DTD中一樣;在我看來,它並沒有被遺漏。 –

+0

@ CMSperberg-McQueen這不是「錯過」,而是一個*慎重的選擇*是爲了省略模型組的任何簡潔的語法,其中元素的順序不傳遞任何信息,至少有一個元素的最小值1的基數和至少一個元素的最大基數大於1,這可能是因爲構建有限自動機以匹配模型組時導致的組合爆炸。 –