您可能会得到不同的答案,这取决于您是想使用 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 的解决方案,但在开放环境中我会远离类似的东西;今天并不是每个人都有兼容的处理器,更不用说规范本身还不是推荐。