xml命名空间的作用(为何mybatis的xml没有命名空间)
xml命名空间到底干嘛的
一句话理解xml命名空间
如果我们把xml理解为类,那么xml命名空间就是xml的包名。
举个例子说明
我们知道xml内的元素是可以随便写的,举个例子,比如小明定义了一个【杯子cup】的xml:
<cup>
<!-- 高度20厘米 -->
<height>20</height>
<!-- 直径12厘米 -->
<diameter>12</diameter>
<cup>
小红也定义了【杯子cup】的另一个xml:
<cup>
<!-- 高度200毫米 -->
<height>200</height>
<!-- 直径120毫米 -->
<diameter>120</diameter>
<cup>
大家都通过xml定义了一个【杯子cup】,但是相同的元素名代表的意思不同。(都是<height>xxx</height>一个单位是cm,一个单位是mm),那这个时候我要配置一个xml定义杯子就麻烦了,其他人怎么知道我定义的杯子用的是厘米还是毫米?这个时候就需要有一个命名空间,告诉别人,我是用的哪个规则(标准)来配置杯子的。
然后我们可以这么配置:
<cup xmlns="xiaohong">
<!-- 高度200毫米 -->
<height>200</height>
<!-- 直径120毫米 -->
<diameter>120</diameter>
<cup>
通过xmlns="xiaohong"来说明我是用的小红的规则。(xmlns即xml namespace的缩写)
怎么定义规则?
细心的小伙伴会发现,当我要配置一个xml时,我咋知道这个xml有哪些元素可以配?如果有一个说明文档,告诉我们怎么配置那就好了。实际上还确实有。当前定义xml配置规则有两种主流的方式:XSD(XML Schema Definition),DTD(Document Type Definition)
废话不多说,直接举个例子(这里还是以上面cup为例):
- 使用XSD定义规则
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="xiaohong"
xmlns="xiaohong"
elementFormDefault="qualified">
<xs:element name="cup">
<xs:complexType>
<xs:sequence>
<xs:element name="height" type="xs:integer"/>
<xs:element name="diameter" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSD比DTD复杂,这里稍微解释下(看不懂也无所谓,大家大概理解下,知道有这么个东西就行):
- 因为XSD本身也是一个xml,所以需要一个命名空间,这里的
xmlns:xs="http://www.w3.org/2001/XMLSchema"即XSD的命名空间。 targetNamespace="xiaohong"说明一下所有定义的元素(cup,height,diameter)来自这个命名空间xmlns="xiaohong"默认命名空间elementFormDefault="qualified"使用此XSD的xml中的元素必须被命名空间限定。
- 适用DTD定义规则
<!-- 根元素是cpu,有两个子元素 height, diameter -->
<!ELEMENT cup (height, diameter)>
<!ELEMENT height (#PCDATA)>
<!ELEMENT diameter (#PCDATA)>
DTD很简单,这里就不展开了,下面看看怎么使用这些规则。
怎么使用规则?
- 引用XSD
<?xml version="1.0"?>
<cup xmlns="xiaohong"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="xiaohong.xsd">
<!-- 高度200毫米 -->
<height>200</height>
<!-- 直径120毫米 -->
<diameter>120</diameter>
<cup>
xmlns="xiaohong"指定命名空间(思考一下如果这里的命名空间是xmlns="xiaoming"呢?这里配置的高度就不是200毫米而是200厘米了,当然一般会引用不同的dtd/xsd),xsi:schemaLocation="xiaohong.xsd"指定使用什么规则文件。(规则文件一般通过一个URL指定,这里简化了一下,大家知道意思就行)
- 引用DTD
<?xml version="1.0"?>
<!DOCTYPE cup SYSTEM "xiaohong.dtd">
<cup>
<!-- 高度200毫米 -->
<height>200</height>
<!-- 直径120毫米 -->
<diameter>120</diameter>
<cup>
我们发现,DTD通过<!DOCTYPE cup SYSTEM "xiaohong.dtd">指定根元素和使用什么dtd规则文件。但我们又发现,DTD居然不要指定namespace!!!是的,xml毕竟是个文本,如果你使用的是DTD,那么是不用指定namespace,因为它不支持。而XSD功能比DTD更多,更完善,所以有说法是XSD是DTD的替代品。不过DTD确实比较简洁。
为何mybatis的xml没有命名空间?
有了上面的铺垫,我们很容易明白为什么mybatis的xml没有指定命名空间了,因为它使用了DTD,所以它没法用xmlns指定namespace(别搞混了,mapper的namespace只是mybatis定义的一个属性,用来指定其对应的mapper类)
看个mapper.xml的例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xchen.demoMapper">
<select id="queryUser" resultType="com.xchen.po.User">
select * from user
</select>
</mapper>
然后我们看下mybatis-3-mapper.dtd的部分内容,(如果对DTD感兴趣的同学,自行查找相关资料哦,这里不展开了):
<!ELEMENT mapper (cache-ref | cache | resultMap* | parameterMap* | sql* | insert* | update* | delete* | select* )+>
<!ATTLIST mapper
namespace CDATA #IMPLIED
>
<!ELEMENT select (#PCDATA | include | trim | where | set | foreach | choose | if | bind)*>
<!ATTLIST select
id CDATA #REQUIRED
parameterMap CDATA #IMPLIED
parameterType CDATA #IMPLIED
resultMap CDATA #IMPLIED
resultType CDATA #IMPLIED
resultSetType (FORWARD_ONLY | SCROLL_INSENSITIVE | SCROLL_SENSITIVE | DEFAULT) #IMPLIED
statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
fetchSize CDATA #IMPLIED
timeout CDATA #IMPLIED
flushCache (true|false) #IMPLIED
useCache (true|false) #IMPLIED
databaseId CDATA #IMPLIED
lang CDATA #IMPLIED
resultOrdered (true|false) #IMPLIED
resultSets CDATA #IMPLIED
>
内容很简单,这里就不解释了。
到此本文结束。拜拜~~
本文详细解释了XML命名空间的作用,如避免元素命名冲突,以及如何通过XSD和DTD定义配置规则。重点揭示Mybatis不使用命名空间的原因——基于DTD的配置方式。
1203

被折叠的 条评论
为什么被折叠?



