如何实现派生响应(XSD)?

时间:2009-08-04 12:44:25

标签: xml xsd

我正在搜索XML架构(XSD)的最佳解决方案。

我有response

<xs:element name="exampleCatalogResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="meta" type="tns:metaType" />
            <xs:element name="data" type="tns:defaultDataType" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

...... defaultDatatype

<xs:complexType name="defaultDataType">
    <xs:sequence>
        <xs:element name="catalog">
            <xs:complexType>
                <xs:sequence maxOccurs="unbounded">
                    <xs:element name="catalogItem" type="tns:catalogItem" />
                </xs:sequence>
            </xs:complexType>
            <xs:unique name="itemIdConstraint">
                <xs:selector xpath="tns:catalogItem" />
                <xs:field xpath="tns:id" />
            </xs:unique>
        </xs:element>
    </xs:sequence>
</xs:complexType>

...和catalogItem

<xs:complexType name="catalogItem">
    <xs:sequence>
        <xs:element name="id" type="xs:nonNegativeInteger" />
    </xs:sequence>
</xs:complexType>

...但现在有一个特殊项目专门用于catalogItem

<xs:complexType name="specialItem">
    <xs:complexContent>
        <xs:extension base="tns:catalogItem">
            <xs:sequence>
                <xs:element name="code" type="xs:string" />
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

现在我需要一个专门的Response用于我的specialItem来回答期望specialItem的请求。

我如何才能实现这一点,而无需撰写另一个defaultDataType只有catalogItem的类型更改为tns:specialItem

2 个答案:

答案 0 :(得分:1)

我认为你不能像XSD那样强制执行共同出现的约束。本着拼图解决方案的精神,这里有一种笨拙的方式来制作你想要的改变副本,而无需手动“编写另一个defaultDataType”:

  1. 在没有命名空间的架构文档中定义上述complexTypes。

  2. <include>它位于第二个架构文档中,它有一个命名空间 - 这为它提供了命名空间。我们可以在许多模式文档中执行此操作,每次都在该不同的命名空间中获取副本。

  3. 在每个模式文档中,扩展catalogItem,以便每个扩展都在自己的命名空间中。

  4. 在最终的架构文档中,包含以上所有内容,并使它们可替换 - 因此它们都可以用作响应。 (或者,您可以将它们全部扩展到另一个模式中的其他响应元素。)

  5. 注意:您需要一种不同的方式来强制执行itemIdConstraint约束,该约束跨越命名空间。另外,我不知道这是否可行。

  6. 这可以通过为每个版本制作defaultDataType的不同副本来实现,因此如果您确实希望它们都使用相同的defaultDataType,则无效。就像我说的那样,这很尴尬,但这是我能看到做你想做的事的唯一方法。我把它作为拼图解决方案提供,而不是实用的解决方案!

答案 1 :(得分:0)

谢谢你的tipps 13ren,

我使用了包容功能。因此,默认的catalogItem在任何地方也用于唯一表达式。现在,如果我在xml中使用它,我可以通过类型指定。

  <tns:catalogItem xsi:type="tns:specialItem">
    <tns:id>0</tns:id>
    <tns:code>tns:code</tns:code>
  </tns:catalogItem>
  <tns:catalogItem xsi:type="tns:specialItem">
    <tns:id>1</tns:id>
    <tns:code>tns:code</tns:code>
  </tns:catalogItem>
  <tns:catalogItem>
    <tns:id>2</tns:id>
    <tns:code>tns:code</tns:code>
  </tns:catalogItem>

所以最后一项是默认项目,上面两项是专门项目。这对我很有用。