在XML Schema(XSD)的开发过程中,经常会遇到需要将多个模式文件拆分管理或者复用已有模式定义的情况,这时候就会用到include和import两个指令。这两个指令都能实现引入外部XSD文件的功能,但在使用规则、命名空间要求等方面存在明显差异,下面来详细分析。

核心差异对比
include和import的核心区别主要体现在命名空间要求、使用场景、引用规则三个方面,具体对比如下:
| 对比维度 | include指令 | import指令 |
|---|---|---|
| 命名空间要求 | 被引入的XSD文件必须与当前文件属于同一个目标命名空间,或者都不定义目标命名空间 | 被引入的XSD文件必须与当前文件属于不同的目标命名空间 |
| 使用场景 | 拆分同一个命名空间下的模式定义,复用同命名空间的公共类型定义 | 引入其他命名空间的模式定义,实现跨命名空间的模式复用 |
| 命名空间声明 | 不需要额外声明被引入文件的命名空间,默认使用当前文件的目标命名空间 | 必须通过namespace属性指定被引入文件的目标命名空间 |
| schemaLocation属性 | 可选,用于指定被引入XSD文件的路径 | 可选,用于指定被引入XSD文件的路径 |
include指令的使用说明
include指令用于引入和当前XSD文件同属一个目标命名空间的外部模式文件,引入后,被引入文件中的所有类型、元素、属性定义都会合并到当前文件的命名空间中,相当于把多个文件的内容拼接成一个完整的模式定义。
使用include的前提条件:
- 当前XSD文件定义了目标命名空间,那么被引入的XSD文件必须定义相同的目标命名空间
- 当前XSD文件没有定义目标命名空间,那么被引入的XSD文件也不能定义目标命名空间
下面是一个include的使用示例,首先定义被引入的公共类型文件common.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/user"
xmlns:tns="http://example.org/user">
<!-- 定义公共的用户基础类型 -->
<complexType name="baseUser">
<sequence>
<element name="id" type="int"/>
<element name="name" type="string"/>
</sequence>
</complexType>
</schema>
然后在主模式文件user.xsd中使用include引入上述文件:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/user"
xmlns:tns="http://example.org/user">
<!-- 引入同命名空间的公共类型定义 -->
<include schemaLocation="common.xsd"/>
<!-- 基于引入的基础类型扩展新的用户类型 -->
<complexType name="fullUser">
<complexContent>
<extension base="tns:baseUser">
<sequence>
<element name="email" type="string"/>
<element name="phone" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<element name="user" type="tns:fullUser"/>
</schema>
import指令的使用说明
import指令用于引入属于不同目标命名空间的外部模式文件,引入后,被引入文件中的定义会保留其原有的命名空间,在当前文件中需要使用对应的命名空间前缀来引用这些定义。
使用import的前提条件:
- 必须通过namespace属性指定被引入XSD文件的目标命名空间,这个命名空间必须和当前文件的目标命名空间不同
- 如果当前文件没有定义目标命名空间,那么被引入的文件可以定义任意目标命名空间
下面是一个import的使用示例,首先定义另一个命名空间的地址模式文件address.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/address"
xmlns:tns="http://example.org/address">
<!-- 定义地址类型 -->
<complexType name="address">
<sequence>
<element name="province" type="string"/>
<element name="city" type="string"/>
<element name="detail" type="string"/>
</sequence>
</complexType>
</schema>
然后在之前的user.xsd中使用import引入地址模式,这里需要修改user.xsd的内容:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/user"
xmlns:tns="http://example.org/user"
xmlns:addr="http://example.org/address">
<!-- 引入不同命名空间的地址模式定义 -->
<import namespace="http://example.org/address" schemaLocation="address.xsd"/>
<!-- 引入同命名空间的公共类型定义 -->
<include schemaLocation="common.xsd"/>
<!-- 基于引入的基础类型扩展新的用户类型,包含地址信息 -->
<complexType name="fullUser">
<complexContent>
<extension base="tns:baseUser">
<sequence>
<element name="email" type="string"/>
<element name="phone" type="string"/>
<element name="address" type="addr:address"/>
</sequence>
</extension>
</complexContent>
</complexType>
<element name="user" type="tns:fullUser"/>
</schema>
常见使用误区
在实际开发中,很多开发者会混淆两个指令的使用场景,常见的误区有:
- 用include引入不同命名空间的XSD文件,这会导致模式验证失败,因为include要求同命名空间
- 用import引入同命名空间的XSD文件,虽然语法上不会报错,但不符合设计初衷,也会让代码结构变得不清晰
- 使用import时忘记声明被引入文件的命名空间,或者声明的命名空间和被引入文件的实际目标命名空间不一致,导致无法正确引用定义
总结
include和import都是XSD中用于引入外部模式文件的指令,核心差异在于命名空间的要求。当需要拆分或复用同一个命名空间下的模式定义时,使用include指令;当需要引入其他命名空间的模式定义时,使用import指令。正确区分两者的使用场景,可以让XSD文件的结构更清晰,也能避免很多不必要的模式验证错误。
XSDincludeimportXML_schema修改时间:2026-06-15 22:15:28