根据子元素属性验证 XML 元素属性值
Validate XML element attribute value depending on child element attribute
我在 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>
我认为您在 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"/>
我找到了用 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>
我在 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>
我认为您在 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"/>
我找到了用 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>