XSD:属性的<xs:选择>等效项

  • 本文关键字:选择 xs XSD 属性 xml xsd
  • 更新时间 :
  • 英文 :


我希望创建一个XML文档,其中必须使用两个已知属性之一定义其元素之一,但不能同时定义两个属性。

例如,我想定义一个"webAddress"元素,如下所示:

 <xs:element name="webAddress">
     <xs:complexType>
         <xs:attribute name="hostName" type="xs:string"/>
         <xs:attribute name="hostAddress" type="xs:string"/>
     </xs:complexType>
 </xs:element>

但我只希望用户能够定义主机名属性(例如,hostName= ")或主机地址(例如,hostAddress=")属性,但不能同时定义两者。 似乎构造为元素完成了这一点。 属性是否有功能等效项,或者是否有更好的方法来解决这个问题?

如果发现我们不能使用 W3C XML 架构执行此操作。我们可以使用嵌入式 schematron 规则,但我们可以通过同时检查元素和属性来对选择元素进行吗?例如像这样:

<xs:choice>
     <xs:element name="webAddress">
         <xs:complexType>
             <xs:attribute name="hostName" type="xs:string"/>
         </xs:complexType>
     </xs:element>
     <xs:element name="webAddress">
         <xs:complexType>
             <xs:attribute name="hostAddress" type="xs:string"/>
         </xs:complexType>
     </xs:element>
  </xs:choice>
您可以使用

"类型"替换,例如

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <!-- Some abstract type - it might define some common parts too. It is abstract and cannot be used directly for instance -->
    <xs:complexType name="abstractType" abstract="true"/>
    <!-- First "children" type of abstract type-->
    <xs:complexType name="hostNameType">
        <xs:complexContent>
            <!-- it is derived from abstractType and adds attribute hostName -->
            <xs:extension base="abstractType">
                <xs:attribute name="hostName" type="xs:string" use="required" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <!-- Second "children" type of abstract type -->
    <xs:complexType name="hostAddressType">
        <xs:complexContent>
            <!-- it is also derived from abstractType and adds attribute hostAddress -->
            <xs:extension base="abstractType">
                <xs:attribute name="hostAddress" type="xs:string" use="required" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <!-- Element of abstractType -->
    <xs:element name="webAddress" type="abstractType" />
</xs:schema>

在实例文档中,您必须指定实际使用的类型:

<?xml version="1.0" encoding="UTF-8"?>
<!-- by xsi:type you defined which "concrete" type is really used -->
<webAddress xsi:type="hostNameType" hostName="String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

<?xml version="1.0" encoding="UTF-8"?>
<webAddress xsi:type="hostAddressType" hostAddress="xxxx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

但是定义有点冗长,而且乍一看并不明显"webAddress"到底是什么类型。但这可能是你的一种方式。

在 XSD 1.1 中,

使用断言或条件类型赋值很容易实现所需的内容,但在 XSD 1.0 中是不可能的。

XSD 1.1目前由Saxon,Xerces和Altova支持。

您可以使用

XSD 密钥实现此目的:

<xs:element name="webAddress">
    <xs:complexType>
        <xs:attribute name="hostName" type="xs:string" use="optional" />
        <xs:attribute name="hostAddress" type="xs:string" use="optional" />
    </xs:complexType>
    <!-- Validate either name or address attribute specified (but not both). -->
    <xs:key name="WebAddressHostNameOrAddressAttributePresent">
        <xs:selector xpath="." />
        <xs:field xpath="@hostName | @hostAddress" />
    </xs:key>
</xs:element>

最新更新