另一个XSD问题 - 如何实现以下XML元素的有效性:
<some-element>
<type>1</type>
<a>...</a>
</some-element>
<some-element>
<type>2</type>
<b>...</b>
</some-element>
子元素( <a>
或 <b>
)应取决于<type>
的内容(也可能是一个属性)。在RelaxNG中它会如此简单 - 但RelaxNG不支持密钥完整性:(
有没有办法在XSD中实现这个?
注意:XML模式版本1.1支持<xs:alternative>
,这可能是一个解决方案,但是没有参考实现(例如libxml2)支持这一点。所以我正在寻找解决方法。我想出的唯一方法是:
<type>1</type>
<some-element type="1">
<!-- simple <xs:choice> between <a> and <b> goes here -->
<a>...</a>
</some-element>
<!-- and now create a keyref between <type> and @type -->
答案 0 :(得分:3)
最佳解决方案是删除<type/>
元素,只有xs:choice
<a/>
和<b/>
,并让使用xml的应用程序对该类型进行排序。
另一种解决方案可能是xs:choice
<a/>
和<b/>
使用xslt脚本来验证与<type/>
相关的<a/>
元素}和<b/>
。
首先针对xmlschema验证xml然后使用xslt对其进行转换,如果转换结果为空,则字符串有效,否则将结果字符串显示为错误消息。
像这样......
的XmlSchema:
<xs:element name="some-element">
<xs:complexType>
<xs:sequence>
<xs:element name="type" type="xs:integer" />
<xs:choice>
<xs:element name="a" type="xs:string" />
<xs:element name="b" type="xs:string" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:demo="uri:demo:namespace">
<xsl:output method="text" />
<xsl:template match="/demo:some-element">
<xsl:if test="type = 1 and not(demo:a)">
When type equals 1 element a is requred.
</xsl:if>
<xsl:if test="type = 2 and not(demo:b)">
When type equals 2 element b is requred.
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
不,XML Schema 1.0无法做到这一点。