1. 命名空间 (Namespace) 的引入
比如有两份 XML 数据
- <labourer>
- <name>Unmi</name>
- <address>fantasia@sina.com</address>
- </labourer>
和
- <labourer>
- <name>Unmi</name>
- <address>Gaoxin Nanyi Road, NanShan District, Shenzhen</address>
- </labourer>
集成在一起时就是
- <labourer>
- <name>Unmi</name>
- <address>fantasia@sina.com</address>
- <address>Gaoxin Nanyi Road, NanShan District, Shenzhen</address>
- </labourer>
注 意到上面,此时计算机是基本无法分辨是何种 addres (判断有无 @ 吗?不妥,再来个别的 address 怎么办)。当然,你说分别换成 <email-address> 和 <post-address> 不行了吗?但这要修改 DTD 文件,也许你没权利修改这些个 DTD 文件,即使行的话,同样再来个别的 address 是不又要修改 DTD 文件?
由此就引入了命名空间 (Namespace) 分别来区分以上那两个 address,甚至更多的 address。有了命名空间,你不必改写 DTD,命名空间一般会用一个 URI 来标定唯一性。加入命名空间后完成 XML 文件如下(未完成):
- <labourer>
- <name>Unmi</name>
- <net:address>fantasia@sina.com</net:address>
- <earth:address>Gaoxin Nanyi Road, NanShan District, Shenzhen</earth:address>
- </labourer>
2. 命名空间的声明与使用
前面那个 XML 可读性是增强了,可是不知你在 IE 打开试了没,会报找不到命名空间的错误:
到未声明的名称空间前缀: 'net'的引用。处理资源 'wmh:C:/Documents%20and%20Settings/Unmi/My%20Documents/XmlPad%20Projects/ns.x...
<net:address>fantasia@sina.com</net:address>
-------------------^
所以接下来我们就要声明命名空间,有两种声明方式 (1) 显式声明,(2) 默认式声明
(1)显式声明
在用到命名空间 (缩写为 ns) 标记 (缩写为 tag) 的外层 (祖先,但通常写在根标记上) 标记中声明,语法如下:
- <ns1:tag1 xmlns:ns1="URI1"
- xmlns:ns2="URI2"
- ...................
- xmlns:nsn="URIn">
然后为 XML 文件中每个标记都加上命名空间(也就是前缀,以下前缀与命名空间等同),修正好的 XML 内容如下
- <earth:labourer xmlns:earth="http://unmi.blogjava.net/earthy"
- xmlns:net="http://unmi.blogjava.net/net">
- <net:name>Unmi</net:name>
- <net:address>fantasia@sina.com</net:address>
- <earth:address>Gaoxin Nanyi Road, NanShan District, Shenzhen</earth:address>
- </earth:labourer>
我们为 XML 文档中出现的每一个标记都使用了前缀,IE 中再次打开,不会有问题了。这里要记住命名空间的关键声明部分语法为 xmlns:ns="URI"。
(2) 默认式声明
是不是觉得上面那个写法太烦琐了,的确。所以就有了默认声明方式,让不带前缀的标签从属于默认命名空间""。声明语法如下
- <tag xmlns="URI"
- xmlns:ns1="URI1"
- ...................
- xmlns:nsn="URIn">
与显式声明的语法只第一行有差异,把两种形式的第一行拿出来就是 <tag xmlns="URI" 和 <ns1:tag1 xmlns:ns1="URI1"。标签本身不带前缀了,并且是直接的 xmlns 等于一个 URI (默认命名空间的 URI),表明这个标签本身就在默认命名空间中,以及子孙标签若未带前缀也是在默认命名空间中的。这样改造过的 XML 文件内容就是:
- <labourer xmlns="http://unmi.blogjava.net/earthy"
- xmlns:net="http://unmi.blogjava.net/net">
- <net:name>Unmi</net:name>
- <net:address>fantasia@sina.com</net:address>
- <address>Gaoxin Nanyi Road, NanShan District, Shenzhen</address>
- </labourer>
是不是简洁多了,因此实际应用中凡有声明命名空间的 XML 文档中,都是以默认方式来声明的。还有,即使是用了显式声明命名空间语法,如果其中仍有未带前缀的标签存在,其实那个标签也是在一个默认的命名空间中,只是没有明确告诉你一个默认的 URI,也许这时默认的 URI 是 ""。如下:
- <earth:labourer xmlns:earth="http://unmi.blogjava.net/earthy"
- xmlns:net="http://unmi.blogjava.net/net">
- <name>Unmi</name>
- <net:address>fantasia@sina.com</net:address>
- <earth:address>Gaoxin Nanyi Road, NanShan District, Shenzhen</earth:address>
- </earth:labourer>
<name> 既不在 earth 中,也不在 net 中,它其实也是在默认的命名空间中,是 ""? 我猜的。
关于 xmlns 那个 URI 说明一点,它只是被借用来唯一标识的名称,看似网址,你可以在那个网页里随意写些东西,或许根本不可到达。
3. XML 使用命名空间的例子
①XSL 文件
- <xsl:stylesheet xmlns:xsl=http://www.w3.org/TR/WD-xsl">
- <xsl:template match="/">
- ........
- <html>
- ..........................................
②XHTML 文件
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <table>
- .....................................
③Spring 2 配置文
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:jee="http://www.springframework.org/schema/jee">
- <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- </bean>
- <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ds"/>
- .............................................
参考:书籍 《XML 与 ASP 网站实作大全》中国铁道出版社 2001年12月第1 版。章节:3-4 使用命名空间避免冲突。