如何定义此XSD?

时间:2015-07-14 23:25:37

标签: xml xsd

现在我有一个可用的XSD:

<Portal layout="blah" />

现在,我想扩展系统,所以我可以做(但我也想支持上面的OLD风格):

<Portal>
  <layout xsi:type="type1">
    <attribute ... />
    <attribute ... />
    <attribute ... />
  </layout>
</Portal>

<Portal>
  <layout xsi:type="type2">
    <otherAttribute ... />
    <someVal ... />
  </layout>
</Portal>

所以我想拥有传统的简单字符串,然后在xsi类型上打开一个更复杂的类型......你不应该把它们混合起来。

这可能吗?

2 个答案:

答案 0 :(得分:1)

我尝试简化这样的问题:元素Portal允许更复杂的组合,例如表示为属性的layout或表示为元素。所以我们有以下内容模型:

<Portal layout="blah" />

<Portal>
    <layout >
       <attribute ... />
       <attribute ... />
    </layout>
</Portal>

为此,您将定义一个基本类型,它是两个内容模型的超集:

<xs:complexType name="PortalBase" abstract="true">
        <xs:sequence>
            <xs:element ref="layout" minOccurs="0"/>
        </xs:sequence>
       <xs:attribute ref="layout"/>
    </xs:complexType>

此基本类型接受portal元素,并将可选layout定义为属性或元素。我们可以通过限制推导出只接受layout属性的第一种类型:

<xs:complexType name="layoutAttribute">
        <xs:complexContent>
            <xs:restriction base="PortalBase">
                <xs:attribute ref="layout" use="required"/> 
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

我们可以派生第二种只接受layout定义为元素的类型:

<xs:complexType name="layoutElement">
        <xs:complexContent>
            <xs:restriction base="PortalBase">
                <xs:sequence>
                    <xs:element ref="layout" minOccurs="1"/>
                </xs:sequence>
                <xs:attribute  ref="layout" use="prohibited"/>
            </xs:restriction>
        </xs:complexContent>

    </xs:complexType>

我们可以在架构中使用它们将portal元素定义为类型PortalBase

  <xs:element name="portal" type="PortalBase"/>

然后我们可以在实例文档中使用它们来声明我们使用的派生类型:

<portal xsi:type= "layoutElement">
    <layout attr1=""/>
</portal>

或:

<portal xsi:type= "layoutAttribute" layout="blah"/>

答案 1 :(得分:0)

您可以使用Portal类型定义中的Mixed Content attribute来实现此目的。

类似的东西:

<xs:element name="Portal">
  <xs:complexType mixed="true"> <!-- this allows "old school" text content -->
    <xs:choice minOccurs="0"> <!-- this allows use of one of the two layout types, or none at all. -->
      <xs:element name="Layout1" type="layout1" />
      <xs:element name="Layout2" type="layout2" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

这里的限制是你不能在同一个“grouping”元素中定义具有相同名称的不同类型的元素(在这种情况下是选择元素)