schema中import与include的区别

许多 Java 项目都涉及多个不同的类和程序包,而不只是一个大的 Java 文件,这是因为模块化可以方便代码的重用、读取和维护。随后,必须将必需的导入语句加入到类中,然后才能使用它们。同样,在 XML 模式中,您必须在各种不同命名空间中管理不同的模式,并需要将必需的导入语句加入到模式中,然后才能使用它们。

可以使用 <import/> 和 <include/> 模式结构组装 XML 模式,当然,以下应是该模式中位于其他任何声明之前的第一个语句:

<schema>
<import namespace="foo" schemaLocation="bar.xsd" />
<include schemaLocation="baz.xsd" />
...
</schema>

当导入的模式具有 targetNamespace 时,将使用 <import />,而当包含的模式未声明 targetNamespace 时,将使用 <include />。

下面,我们将介绍一个示例,该示例涉及两个模式 A 和 B,且 A 引用 B 中声明的项目。

情况 I
如果两个模式都有 targetNamespace,且模式 A 的 targetNamespace (tnsA) 不同于模式 B 的 targetNamespace (tnsB),则 A 必须导入 B。

<import namespace="tnsB" schemaLocation="B.xsd">

但 A 导入 B 时和 A 包含 B 时不指定命名空间是一个错误。

情况 II
如果两个模式都包含 targetNamespace,且模式 A 的 targetNamespace (tnsAB) 与模式 B 的 targetNamespace (tnsAB) 相同,则 A 必须包含 B。

<include schemaLocation="B.xsd">

A 导入 B 是错误的。

情况 III
如果模式 A 和 B 都没有 targetNamespace。这种情况下,A 必须包含 B。

<include schemaLocation="B.xsd" />

情况 IV
如果模式 A 没有 targetNamespace,而模式 B 包含 targetNamespace (tnsB),则 A 必须导入 B。
<import namespace="tnsB" schemaLocation="B.xsd" />

A 包含 B 是错误的,这是因为 B 包含一个 targetNamespace。

情况 V
如果模式 A 包含 targetNamespace (tnsA),而模式 B 不包含 targetNamespace,情况又将如何?A 应包含 B。但如果我认为在本例中,A 应导入 B,情况将如何?实际上,在这种情况下,A 可以导入或包含 B,且这两个操作都是合法的,但效果并不相同。

如果 A 包含 B,则所包含的来自 B 的所有项目将获取 A 的命名空间。这样的包含被称作 可变式 包含。

如果您不希望发生这样的可变式效果,则必须在不指定命名空间情况下完成导入。没有 namespace 属性的导入允许对不包含目标命名空间的组件进行非限定性引用。

<import schemaLocation="B.xsd">

多次导入或包含一个模式不会产生错误,这是因为模式处理器可以检测这种情况并不再加载已加载的模式。因此,A.xsd 导入 B.xsd 和 C.xsd 并不产生错误;B.xsd 和 C.xsd 各自单独导入 A.xsd。循环引用不会产生错误,但强烈建议您不要使用它。

顺便说明的是,一个类似 <import /> 的简单导入也是合法的。该方法只允许对不包含目标命名空间的外部组件进行非限定性引用,而不提供任何有关其所在位置的信息提示。模式处理器将利用某种机制提示出错或查找未知项目,因模式处理器而异。但使用 <include /> 是非法的。

经验法则:

<include/> - 它的作用与在包含模式中以内联方式定义被包含的模式相当。
<import/> -如果被导入的模式与导入模式的 targetNamespace 不同则始终使用 <import/>。

本文来源:http://blog.sina.com.cn/s/blog_53ed05ad010001eb.html


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。