如何定义具有强制属性的“任何元素”

时间:2012-10-01 03:21:51

标签: xsd

我有一个XML,它可以包含任何元素,例如:

<AnyElements>
  <Any1 id="any1" />
  <Any2 id="any2" />
  ...
</AnyElements>

id属性是强制性的。

我如何定义这样的xsd?

<xs:element name="AnyElements" type="AnyRootType" />
<xs:complexType name="AnyRootType">
  <xs:sequence>
    <xs:any type="AnyChildType" minOccurs="1" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType> 

<xs:complexType name="AnyChildType">
  <xs:attribute ref="id" use="required"/>
</xs:complexType>

<xs:attribute name="id" type="xs:string"/>

1 个答案:

答案 0 :(得分:0)

这完全取决于您将如何定义处理模型。以下是您需要首先考虑的一些事项。

any粒子不能用类型约束。它附带一个名为processContents的属性,可以跳过宽松,默认为严格。一旦你完全理解它的含义,那么使用 跳过 只是意味着你将无法强制执行你的强制属性 - 处理器就会这样做,“跳过” 。如果您将其设置为 lax ,则仅当描述内容的XSD实际可用时才会处理,否则它将跳过;第三个选项 严格 ,要求描述此额外内容的XSD可用 - 期限。

因此,只有在验证期间描述“any”的XSD可用时,any粒子才能工作。我想到的选项是一种限制,但它的优点是最接近任何“精神”,因为它不必从特定的基类型派生,或引用一些引用;为此,一个类似于约束你的要求的关键约束:

    <xsd:key name="ofid">
        <xsd:selector xpath="*"/>
        <xsd:field xpath="@id"/>
    </xsd:key>

实际上,键使得属性成为必需。缺点可能是每个值也必须是唯一的。也许使用名为id的属性,它是预期的;如果你希望将模式应用于诸如age之类的东西,那么它将无效。

如果您认为在运行时可用的XSD是可接受的,那么其他替代方案可能包括使用抽象元素或具有抽象类型的元素。好处是它会带来一种更有纪律的方法(你将从一开始就明确地设置约束),并且不会放置值约束的唯一性。缺点可能是它创建了与另一个描述“合同”的XSD的耦合 - 你的强制属性。

更新:根据您的评论,以下是基于替代组的替代方案。我尽量保留旧的XSD组件名称。

Contract.xsd :这包含合同的组成部分。它基本上描述了你的替换组的负责人;它表示需要id属性。

<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:complexType name="AnyChildType" abstract="true">
        <xsd:attribute name="id" use="required"/>
    </xsd:complexType>

    <xsd:element name="AnyElement" abstract="true" type="AnyChildType"/>
</xsd:schema>

GenericInstance.xsd :它描述了“通用”文档的根目录。它在您定义的根元素的上下文中“合并”您的契约。

<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="Contract.xsd"/>

    <xsd:element name="AnyElements" type="AnyRootType"/>
    <xsd:complexType name="AnyRootType">
        <xsd:sequence>
            <xsd:element ref="AnyElement" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

SpecificInstance1.xsd :特定合同。

<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="Contract.xsd"/>

    <xsd:element name="SomeElement1" substitutionGroup="AnyElement">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="AnyChildType">
                    <xsd:annotation>
                        <xsd:documentation>Any content goes.</xsd:documentation>
                    </xsd:annotation>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

SpecificInstance2.xsd :另一个合同(显示不同的创作风格)。

<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="Contract.xsd"/>

    <xsd:element name="SomeElement2" substitutionGroup="AnyElement" type="SomeElement2Type"/>
    <xsd:complexType name="SomeElement2Type">
        <xsd:complexContent>
            <xsd:extension base="AnyChildType">
                <xsd:annotation>
                    <xsd:documentation>Any content goes.</xsd:documentation>
                </xsd:annotation>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
</xsd:schema>

在视觉上,这就是他们联系在一起的方式。您可以看到XSD之间的耦合保持最小。

enter image description here

示例XML,在您的通用实例定义的范围内有效,以及特定的XML。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<AnyElements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SomeElement1 id="1"/>
    <SomeElement2 id="1"/>
</AnyElements>

如果您仅限于使用一个XSD验证您的XML,则下面只是一个XSD:

<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:include schemaLocation="GenericInstance.xsd"/>
    <xsd:include schemaLocation="SpecificInstance1.xsd"/>
    <xsd:include schemaLocation="SpecificInstance2.xsd"/>
</xsd:schema>

我已经在.NET上运行XSD 1.0测试了上述内容;能够在XSD 1.1上运行或在其他XSD处理器中运行特定功能会使我所说的一些内容无效。