【发布时间】:2021-01-04 08:09:46
【问题描述】:
我在某个命名空间中有一个用于某个 XML 模式的 XSD,我们称之为http://mydomain/schema1。以下是相应 XML 文件的示例:
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="http://mydomain/schema1">
<a>
<b />
</a>
</root>
现在,我想定义一个新模式,我们称之为http://mydomain/schema2,它扩展第一个模式,允许我在现有元素中放置新元素,如下所示:
<root xmlns="http://mydomain/schema1" xmlns:s2="http://mydomain/schema2">
<a>
<b>
<s2:c>...</s2:c>
</b>
</a>
</root>
这可能使用 XML 模式吗?给定http://mydomain/schema1 的以下 XSD,http://mydomain/schema2 的 XSD 会是什么样子?它将如何修改 B 的复杂类型定义?
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="schema1"
targetNamespace="http://mydomain/schema1"
elementFormDefault="qualified"
xmlns="http://mydomain/schema1"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="Root" />
<xs:complexType name="Root">
<xs:sequence>
<xs:element name="a" type="A" />
<!-- ... -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="A">
<xs:sequence>
<xs:element name="b" type="B" />
<!-- ... -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="B">
<xs:sequence>
<!-- ... -->
</xs:sequence>
</xs:complexType>
</xs:schema>
实际目标是获取一个符合http://mydomain/schema1(仅限!)的输入文档,然后返回它扩展了http://mydomain/schema2 定义的元素。我想让我的最终用户根据各自的架构定义验证输入文档和扩展返回文档,因此我需要发布这两个架构。
我们当前的解决方法是解析原始 XSD,修改架构定义以包含其他元素,然后将所有命名空间更新为 http://mydomain/schema2 并发布生成的架构。结果看起来像是http://mydomain/schema1 的超集,但实际上为所有元素定义了不同的命名空间,即使是那些已经存在于http://mydomain/schema1 中的元素。当我们获取实际的输入 XML 时,我们首先重写命名空间,然后添加新元素。这行得通,但感觉有点笨拙 - 当然,http://mydomain/schema2真的不是http://mydomain/schema1 的超集,它只是看起来像一个。
【问题讨论】:
-
您可以简单地导入包含新子元素的 XSD,并将可选元素引用添加到复杂类型 B。您考虑过这种方法并拒绝了吗?
-
您能否详细说明“导入...并添加可选元素引用”的含义?你的意思是,修改原来的 XSD 模式定义?目标是获取一个符合 schema1(仅!)的输入文档,然后返回它扩展了由 schema2 定义的元素。我想让我的最终用户针对不同的模式验证输入文档和扩展返回文档,所以我需要发布这两个模式。我也会将该信息添加到问题中。
-
@kimbert 我已经添加了更多关于实际目标和我们当前解决该问题的方法的信息。也许这就是你要问的。