Xsd 不同的子元素取决于属性/元素值

Xsd 不同的子元素取决于属性/元素值,xsd,xsd-1.0,Xsd,Xsd 1.0,另一个XSD问题—如何确保以下XML元素都有效: <some-element> <type>1</type> <a>...</a> </some-element> <some-element> <type>2</type> <b>...</b> </some-element> 1. ... 2. ... 子元素(或或)应取决于的内

另一个XSD问题—如何确保以下XML元素都有效:

<some-element>
  <type>1</type>
  <a>...</a>
</some-element>

<some-element>
  <type>2</type>
  <b>...</b>
</some-element>

1.
...
2.
...
子元素(或
)应取决于
的内容(也可以是属性)。这在RelaxNG中非常简单-但RelaxNG不支持密钥完整性:(

有没有办法在XSD中实现这一点

注意:XML模式版本1.1支持
,这可能是一个解决方案,但afaik没有参考实现(例如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 -->
1
...

不,XML Schema 1.0无法做到这一点。

最好的解决方案是删除
元素,并且只有
xs:choice,让使用XML的应用程序对类型进行排序

另一种解决方案可能是为
提供
xs:choice
,并使用xslt脚本对
元素进行与
相关的验证

首先根据xmlschema验证xml,然后使用xslt对其进行转换,如果转换的结果是空字符串,则它是有效的,否则将结果字符串显示为错误消息

像这样的

XmlSchema:


Xslt:


当类型等于1时,需要元素a。
当类型等于2时,需要元素b。
  <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>
<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>