2015-06-22 218 views
0

我有這樣的XML:驗證XML元素屬性值取決於子元素屬性

<generator Mode="High"> 
    <GenMode name="Normal" kV="90" mA="0.5" /> 
    <GenMode name="High" kV="160" mA="0.7" /> 
</generator> 

generator/@mode應該是有效的,只有當它匹配generator/GenMode/@name之一。是否可以用XSD 1.0

現在我使用的XSD文件此規則對於這個元素:

<xs:element name="generator"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element name="GenMode" maxOccurs="unbounded" type="GenModeType" /> 
    </xs:sequence> 
    <xs:attribute name="Mode" use="required" type="xs:string"/> 
    </xs:complexType> 
    <xs:key name="GenModeName"> 
    <xs:selector xpath="GenMode"/> 
    <xs:field xpath="@name"/> 
    </xs:key> 
</xs:element> 
<xs:complexType name="GenModeType"> 
    <xs:attribute name="name" use="required" type="xs:string"/> 
    <xs:attribute name="kV" use="required" type="xs:integer"/> 
    <xs:attribute name="mA" use="required" type="xs:decimal"/> 
</xs:complexType> 
+0

你是什麼意思「我想檢查」?如果XML的GenMode具有與生成器/ @模式相同的名稱,那麼它應該是有效的或無效的?如果你想要一個GenMode必須始終與生成器/ @模式具有相同的名稱,那麼可能只能使用XSD 1.1 – sergioFC

+0

@sergioFC'generator/@ mode'只有在其中一個GenMode具有一樣的名字。 –

+0

您將需要使用XSD 1.1。在XSD1.0中我能想到的最好的方法是將generator/@ mode類型定義爲xs:ID,並在GenMode/@模式類型爲xs:IDREF的序列開始時添加一個新元素GenMode。 – sergioFC

回答

0

我找到了驗證屬性值的方法,用XSD 1.0,它不應該只引用第一個子元素。

<xs:element name="generator"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element name="GenMode" maxOccurs="unbounded" type="GenModeType"/> 
    </xs:sequence> 
    <xs:attribute name="Mode" use="required" type="xs:string"/> 
    </xs:complexType> 
    <xs:unique name="GenModeNameUniquenessCheck"> 
    <!-- check for uniqueness @name attribute of all GenMode elements --> 
    <xs:selector xpath="GenMode"/> 
    <xs:field xpath="@name"/> 
    </xs:unique> 
    <xs:keyref name="GeneratorModeValid" refer="GenModeNameUniquenessCheck"> 
    <!-- check generator/@Mode is one of generator/GenMode/@name --> 
    <xs:selector xpath="."/> 
    <xs:field xpath="@Mode"/> 
    </xs:keyref>  
</xs:element> 
<xs:complexType name="GenModeType"> 
    <xs:attribute name="name" use="required" type="xs:string"/> 
    <xs:attribute name="kV" use="required" type="xs:integer"/> 
    <xs:attribute name="mA" use="required" type="xs:decimal"/> 
</xs:complexType> 
1

我認爲你可以在XSD 1.0做不創建具有不同名稱的元素最接近的是定義了generator/@Mode應該是指第一GenMode/@name

<xs:element name="generator"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="GenMode" type="GenModeType"> 
       <!-- This is the key of the first GenMode --> 
       <xs:key name="firstGenModeKey"> 
        <xs:selector xpath="."/> 
        <xs:field xpath="@name"/> 
       </xs:key> 
      </xs:element> 
      <xs:element name="GenMode" minOccurs="0" maxOccurs="unbounded" type="GenModeType" /> 
     </xs:sequence> 
     <xs:attribute name="Mode" use="required" type="xs:string"/> 
    </xs:complexType> 
    <!-- Mode attribute should refer to firstGenModeKey --> 
    <xs:keyref refer="firstGenModeKey" name="ign"> 
     <xs:selector xpath="."/> 
     <xs:field xpath="@Mode"/> 
    </xs:keyref> 
    <!-- Every genMode/@name should be unique, so you can use xs:unique also --> 
    <xs:key name="GenModeName"> 
     <xs:selector xpath="GenMode"/> 
     <xs:field xpath="@name"/> 
    </xs:key> 
</xs:element> 
<xs:complexType name="GenModeType"> 
    <xs:attribute name="name" use="required" type="xs:string"/> 
    <xs:attribute name="kV" use="required" type="xs:integer"/> 
    <xs:attribute name="mA" use="required" type="xs:decimal"/> 
</xs:complexType> 

如你所知,如果你使用XSD 1.1,你只需要添加一個斷言這樣的例子之一:

<xs:assert test="count(GenMode[@name = ../@Mode]) = 1"/>