2010-08-12 78 views
0

我想定義一個驗證以下XML的XSD。定義XSD以驗證同一元素允許的XML屬性組

<parameters> 
    <param name="Maximum Error Threshold" type="integer">10</param> 
    <param name="Auto Shutdown Timeout Duration" type="integer" unit="seconds">300</param> 
    <param name="Flow Rate Adjusment" type="integer" unit="litrePerSec">0.5</param> 
    <param name="Configuration Download Time" type="timeofday" format="timestring">03:20</param> 
    <param name="Maximum Issue Value" type="integer" unit="cents" format="numericfloat">145.50</param> 
</parameters> 

我現在有一個架構它看起來像:

<xs:element name="parameters"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element maxOccurs="5" minOccurs="5" ref="param"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="param"> 
    <xs:complexType> 
     <xs:simpleContent> 
     <xs:extension base="xs:NMTOKEN"> 
      <xs:attribute name="name" use="required" type="AttributeNames"/> 
      <xs:attribute name="type" use="required" type="AttributeTypes"/> 
      <xs:attribute name="format" use="optional" type="AttributeFormats"/> 
      <xs:attribute name="unit" use="optional" type="AttributeUnits"/> 
     </xs:extension> 
     </xs:simpleContent> 
    </xs:complexType> 
    </xs:element> 
    <xs:simpleType name="AttributeNames"> 
    <xs:restriction base="xs:token"> 
     <xs:enumeration value="Maximum Error Threshold"/> 
     <xs:enumeration value="Auto Shutdown Timeout Duration"/> 
     <xs:enumeration value="Flow Rate Adjusment"/> 
     <xs:enumeration value="Configuration Download Time"/> 
     <xs:enumeration value="Maximum Issue Value"/> 
    </xs:restriction> 
    </xs:simpleType> 
    <xs:simpleType name="AttributeTypes"> 
    <xs:restriction base="xs:NCName"> 
     <xs:enumeration value="integer"/> 
     <xs:enumeration value="timeofday"/> 
    </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="AttributeFormats"> 
    <xs:restriction base="xs:NCName"> 
     <xs:enumeration value="timestring"/> 
     <xs:enumeration value="numericfloat"/> 
    </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="AttributeUnits"> 
    <xs:restriction base="xs:NCName"> 
     <xs:enumeration value="seconds"/> 
     <xs:enumeration value="litrePerSec"/> 
     <xs:enumeration value="cents"/> 
    </xs:restriction> 
    </xs:simpleType> 

這工作。但它並沒有給我完整的驗證。 我想確保'參數'元素中存在適當的屬性(並且這些屬性包含適當的值),具體取決於屬性包含的內容。

例如;

如果「名稱」屬性=「自動關閉超時持續時間」,則該「類型」是必需的,只能是「整數」和「單元」是必需的,可以是「小時「,」分鐘「或」秒「。

但如果「名稱」屬性=「最大誤差閾值」,那麼「類型」是必需的,只能是「整數」,但「單元」是不允許的。

所以我決定分別描述每個參數;即是這樣的:

<xs:complexType name="MaxErrorParam"> 
    <xs:simpleContent> 
     <xs:extension base="xs:NMTOKEN"> 
     <xs:attribute name="name" fixed="Maximum Error Threshold"/> 
     <xs:attributeGroup ref="CounterParameterAttributes"/> 
     </xs:extension> 
    </xs:simpleContent> 
    </xs:complexType> 

    <xs:complexType name="AutoShutdownParam"> 
    <xs:simpleContent> 
     <xs:extension base="xs:NMTOKEN"> 
     <xs:attribute name="name" fixed="Auto Shutdown Timeout Duration"/> 
     <xs:attributeGroup ref="TimeOutParameterAttributes"/> 
     </xs:extension> 
    </xs:simpleContent> 
    </xs:complexType> 

    <xs:attributeGroup name="CounterParameterAttributes"> 
    <xs:attribute name="type" use="required" fixed="integer"/> 
    </xs:attributeGroup> 

    <xs:attributeGroup name="TimeOutParameterAttributes"> 
    <xs:attribute name="type" use="required" fixed="integer"/> 
    <xs:attribute name="format" use="required" type="TimeUnitsType"/> 
    </xs:attributeGroup> 

    <xs:simpleType name="TimeUnitsType"> 
    <xs:restriction base="xs:NCName"> 
     <xs:enumeration value="minutes"/> 
     <xs:enumeration value="seconds"/> 
     <xs:enumeration value="hours"/> 
    </xs:restriction> 
    </xs:simpleType> 

但這意味着我需要如下定義「PARAM」元件;這會導致錯誤,因爲元素'參數'使用不同類型定義了兩次。

<xs:element name="parameters"> 
    <xs:complexType> 
     <xs:all> 
     <xs:element name="param" type="MaxErrorParam"/> 
     <xs:element name="param" type="AutoShutdownParam"/> 
     etc... 
     </xs:> 
    </xs:complexType> 
    </xs:element> 

任何人都可以請建議一個解決方案或指向正確的方向嗎?

回答

0

沒有人回答這個問題,我希望這對你仍然很有意思。您列出的方法不起作用:XML Schema無法驗證表單的約束「如果元素X包含某些內容,則檢查Y」。同樣,你不能在同一個容器中擁有兩個具有相同名稱但不同類型的元素,就像你說的那樣。

但是,你可以做的是:1)建立在參數子元素與value名稱和類型的xs:anySimpleType和2)使用原生XML Schema類型覆蓋機制(XSI:類型):

<parameters xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <param name="Maximum Error Threshold"> 
     <value xsi:type="xs:int">10</value> 
    </param> 
</parameters>