xml - XSD:元素和属性之间的选择

标签 xml jaxb xsd

我想要一个具有内容或特定属性但不能同时具有两者的元素。 该元素可以如下所示:

<Location ref="blah"/>

或者这个:

<Location> <aaaLocation>...</aaaLocation> <Location>

但不是这样的:

 <Location ref="blah"> <aaaLocation>...</aaaLocation> <Location>

我尝试了一些变体:

<xs:complexType name="FatherOfLocatiion">
        <xs:choice>
            <xs:element name="Location">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name ="aaaLocation" type="Alocation"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="Location">
                <xs:complexType>
                    <xs:attribute name="ref" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:choice>
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>

该模式在 XML spy 等工具中是有效的,但是当我尝试使用 jaxb 从中生成对象时,出现以下错误:

名称为“Location”、具有不同类型的多个元素出现在模型组中。

还有其他方法可以强制执行吗?

最佳答案

在 XSD 1.0 中有一种方法可以做到这一点,它涉及使用 xsi:type属性; xsi:type 是一个 XML 属性,但是,XSD 感知 XML 处理器将根据您的需要以不同方式对待它。 (为了完整起见,此方法是 XSD 1.1 中替代类型的前身,是实现您想要的目标的另一种方法)。

给定以下 XSD 1.0:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="Location"/>
    <xsd:complexType name="LocationWithRef">
        <xsd:attribute name="ref" type="xsd:string" use="required"/>
    </xsd:complexType>
    <xsd:complexType name="LocationWithContent">
        <xsd:sequence>
            <xsd:element name="a"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema> 

以下 XML 是有效的,但没有其他组合;具有属性:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<Location xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LocationWithRef" ref="a"/>

与元素:

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

以上内容足以模拟您为 XML 世界指出的内容;但是,对于 XSD 代码绑定(bind)技术,您需要采取额外的步骤使其变得友好,例如 JAXB(或 .NET)。关键是将它们与一个抽象基类型(下面是 ALocation)链接起来。

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="Location" type="ALocation"/>
    <xsd:complexType name="ALocation" abstract="true"/>
    <xsd:complexType name="LocationWithRef">
        <xsd:complexContent>
            <xsd:extension base="ALocation">
                <xsd:attribute name="ref" type="xsd:string" use="required"/>                
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType name="LocationWithContent">
        <xsd:complexContent>
            <xsd:extension base="ALocation">
                <xsd:sequence>
                    <xsd:element name="a"/>
                </xsd:sequence>             
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
</xsd:schema> 

上面的优点是,它基于几乎所有 XSD 处理器都支持的技术,给出了你所要求的(唉,xsi:type 可能不符合你或其他人的喜好)那里。

不幸的是,XSD 1.1 支持非常有限,如果我不得不猜测,JAXB(您似乎对此感兴趣)将支持它的一部分需要一段时间,更不用说其他 XSD 代码绑定(bind)解决方案...

关于xml - XSD:元素和属性之间的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22812489/

相关文章:

android - 键盘弹起时如何调整 ListView 的大小?

java - 如何让ImageView在屏幕上随机移动而不脱离屏幕?

java - "no value for rss",虽然它显然在那里

java - Maven + Resteasy JAXB 找不到内容类型 application/xml 的 writer

c# - 如何在 C# 中动态创建 XML 架构?

java - xjc 和 XSD 的选择

c# - 使用 XElement 追加 XML

用默认值初始化的JAXB对象

java - 通过 JMS 发送的 XML 消息 (JAXB) 为空

xml - 为什么 XPath 不适用于 xmlns 属性