XSD:A 等同于属性

问题描述 投票:1回答:3

我希望创建一个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属性(例如,hostName =“”)或hostAddress(例如,hostAddress =“”)属性,但不能同时定义两者。似乎该构造为元素完成了此操作。是否有功能上等效的属性,或者有更好的方法来解决此问题?

[如果发现我们无法使用W3C XML Schema执行此操作。我们可以使用嵌入的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 xsd
3个回答
1
投票

您可以使用“类型”替换,例如

<?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”实际上是什么类型也不是很明显。但这可能是您的一种方式。


0
投票

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

[SSDon,Xerces和Altova当前支持XSD 1.1。


0
投票

您可以使用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>
© www.soinside.com 2019 - 2024. All rights reserved.