【问题标题】:XSD: One element shall be allowed in different formsXSD:一个元素应允许以不同的形式
【发布时间】:2026-01-08 06:05:03
【问题描述】:

使用 XSD,我想定义一个可以以三种不同形式出现的复杂元素:

<Scope Name="foo" />  <!-- no children -->
<Scope Name="foo" Src="bar" /> <!-- When Src is present, there must be no children! -->
<Scope Name="foo"><!-- other children --></Scope>

在第三种情况下,明确定义了可以作为子元素出现的内容(例如所有三种类型的“Scope”)。重要的是,具有“Src”属性的 Scope 元素必须为空!

此外,在不同的地方,我只希望允许特定类型的元素。例如,在根标签内,我想只允许第三种类型的 Scope 元素;在大多数情况下,我想允许所有情况。这就是问题所在:如何解决这个问题?

到目前为止我所做的:我为我可以在 .但是,我不能使用:

<xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="Scope" type="type_Scope_WithSrc" />
    <xs:element name="Scope" type="type_Scope_WithContent" />
    <xs:element name="Scope" type="type_Scope_Base" />
</xs:choice>

我试图创建一个联合,但联合只允许用于简单类型。

我还尝试定义一个整体类型“type_Scope”,它使用 xs:choice 来包含它们。但是 xs:choice 将包括 xs:elements 在这种情况下也需要一个名称:-(

你能告诉我如何处理这个问题吗?

请不要告诉我使用 XSD 是不可能的 :-( :-(

谢谢

问候 divB

【问题讨论】:

    标签: xml xsd stylesheet


    【解决方案1】:

    您可能会得到不同的答案,这取决于您是想使用 XSD 1.1 还是 XSD 1.0 来实现这一点;我假设您正在寻求 1.0 解决方案,我将在此处描述(我认为 1.1 尚不实用)。

    如果您想保留元素名称并改变其内容,您唯一的选择是使用 xsi:type。无需选择,只需使用单个 Scope 元素;使其类型成为复杂类型,具有名为“名称”的属性。让其他两种类型从此基本类型扩展。你就完成了。

    注意:我使用了一个基本抽象类型作为一种机制来通知人们其他类型应该进入那里;事实上,即使没有它,它也能工作,从一开始就使用 type_Scope_Base。

    XSD:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
        <xsd:complexType name="type_Scope_BaseA" abstract="true">
        </xsd:complexType>  
    
        <xsd:complexType name="type_Scope_Base">
            <xsd:complexContent>
                <xsd:extension base="type_Scope_BaseA">
                    <xsd:attribute name="Name" type="xsd:string"/>      
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>  
    
        <xsd:complexType name="type_Scope_WithSrc">
            <xsd:complexContent>
                <xsd:extension base="type_Scope_Base">
                    <xsd:attribute name="Src" type="xsd:string"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    
        <xsd:complexType name="type_Scope_WithContent">
            <xsd:complexContent>
                <xsd:extension base="type_Scope_Base">
                    <xsd:sequence>
                        <xsd:any maxOccurs="unbounded" namespace="##other" processContents="lax"/>
                    </xsd:sequence>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    
        <xsd:element name="root">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element ref="Scope"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    
        <xsd:element name="Scope" type="type_Scope_BaseA"/>
    
    </xsd:schema>
    

    这是三个示例 XML,均有效。第一个内容模型来自type_Scope_Base

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
        <Scope xsi:type="type_Scope_Base" Name="Name1"/>
    </root>
    

    这是来自type_Scope_WithSrc的内容模型。

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
        <Scope xsi:type="type_Scope_WithSrc" Name="Name1" Src="Src1"/>
    </root>
    

    还有来自type_Scope_WithContent的内容模型。

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
        <Scope xsi:type="type_Scope_WithContent" Name="Name1">
            <me:hello.you xmlns:me="http://paschidev.com"/>
        </Scope>
    </root>
    

    如果你想允许标签名称的变化,而不是选择你可以在那里放置一个替换组的头部,这至少可以给你一个没有 xsi:type 的解决方案。

    还有基于 XSD 1.1 的解决方案,但在开放环境中我会远离类似的东西;今天并不是每个人都有兼容的处理器,更不用说规范本身还不是推荐。

    【讨论】:

      最近更新 更多