2012-01-09 64 views
3

我的架構允許一個特定的元素是可選的,但是當我在文件中遇到不同也可選元素以後,我需要上一個存在。我如何通過XSD確保這一點?XML架構:需要一個要素是存在當另一個存在

實施例:

<settings> 
    <file name="narf.txt"/> 
    <metafile name="narf.meta"/> 
    <filtermeta>true</filtermeta> 
</settings> 

應該是有效的,

<settings> 
    <file name="narf.txt"/> 
    <metafile name="narf.meta"/> 
</settings> 

<settings> 
    <file name="narf.txt"/> 
</settings> 

應該是有效的太,

<settings> 
    <file name="narf.txt"/> 
    <filtermeta>true</filtermeta> 
</settings> 

應該無效。

+0

看起來這是不可能的XML模式1.0 - 未來的規範可能允許IF-THEN-ELSE,至少它正在討論。 – brandstaetter 2012-01-09 12:58:27

回答

3

請嘗試以下架構定義:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
    <xs:element name="settings"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="file"> 
      <xs:complexType> 
      <xs:attribute name="name" type="xs:string"/> 
      </xs:complexType> 
     </xs:element> 
     <xs:sequence minOccurs="0"> 
      <xs:element name="metafile"> 
      <xs:complexType> 
       <xs:attribute name="name" type="xs:string"/> 
      </xs:complexType> 
      </xs:element> 
      <xs:element minOccurs="0" name="filtermeta" type="xs:string"/> 
     </xs:sequence> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

我使用xmllint運行鍼對該模式的第一個三個例子,他們正確地驗證。第四個示例失敗:

cvc-complex-type.2.4.a: Invalid content was found starting with element 'filtermeta'. One of '{metafile}' is expected. 

正如預期的那樣。

+0

謝謝。雖然這解決了我爲解釋我的問題而發佈的一個簡單示例,但它並不能解決潛在的問題,特別是在架構邏輯和層次結構中元素進一步分開的情況下尤其如此。它可能會使代碼重複工作,但這只是醜陋的。 – brandstaetter 2012-01-10 07:44:05

+1

同意。對於更一般的情況,它會迅速變得非常不愉快。像Schematron這樣的東西在這裏會更好 - 你可以放鬆XSD,這樣它就可以關注基本結構和輸入約束。然後,'交叉字段'驗證規則(例如,如果元素'A'存在,元素'B'必須存在)可以寫爲Schematron規則。 – 2012-01-10 15:54:01

+0

例如,可以編寫一個Schematron規則對提供的測試的情況下爲: '<架構的xmlns =「http://purl.oclc.org/dsdl/schematron」> <規則上下文=「/設置/ filtermeta 「> <斷言測試=」 ../元文件「>如果filtermeta存在,元文件也必須存在 ' – 2012-01-10 15:59:01

0

你可以有filtermeta作爲一個可選屬性爲metafile元素。

相關問題