3

另一个 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>,这可能是一个解决方案,但 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 -->
4

2 回答 2

3

最好的解决方案是删除<type/>元素,只有一个xs:choicefor<a/><b/>,让使用 xml 的应用程序对类型进行排序。

另一种解决方案可能是使用xs:choicefor<a/><b/>使用 xslt 脚本来验证与and相关的<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>
于 2010-05-11T19:38:26.933 回答
2

不,XML Schema 1.0 不能做到这一点。

于 2010-05-11T19:29:23.013 回答