最近繼續看Struts,在看struts.xml配置的時候看到這個:
[html]view plaincopy
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee?http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
想起了自己在以前的博客中有人問到這個問題,然后自己對XML也比較陌生,所以系統性地學了一下,把基本的屬性,XML DOM(其實和HTML DOM類似),DTD,XML Schema,xmlns理了一次。
類似這種技術知識的,直接谷歌就好,這樣會省很多時間。
先是從StackOverFlow看到:http://stackoverflow.com/questions/1181888/what-does-xmlns-in-xml-mean
問:我在xml文件中看到這句話,xmlns,這是什么呢?
[html]view plaincopy
xmlns:android="http://schemas.android.com/apk/res/android"
答:它定義了一個XML命名空間。
在你的例子中,命名空間前綴是android,命名空間的uri為
[html]view plaincopy
http://schemas.android.com/apk/res/android
在文檔中,你可以看到這樣的元素。
這樣認為,命名空間前綴就是一個變量,以簡短的名字表示整個命名空間uri。
和這樣寫是等價的。XML解析器讀取的時候就是這樣讀取的。
參考:http://www.sitepoint.com/xml-namespaces-explained/#
參考的文章寫得比較好,w3c在這部分講得過于簡單,所以還是翻譯一下這篇文章。
XML Namespaces Explained
為什么我們需要XML命名空間?
這里有存在命名空間的兩個基本需要:
1、消除兩個剛好同名的元素的歧義。
2、將共同idea的元素分組在一起。
這些描述有點模糊,直接看例子:
消除兩個剛好同名的元素的歧義
考慮一下:
* 在(x)html文件中有table元素,同時XSL-FO(現在稱為XSL,作用可以類比CSS對Html的作用)里面也有同名的元素。
* a,title和style都是(x)html和SVG(SVG 是使用 XML 來描述二維圖形和繪圖程序的語言)的元素。
好了,那你怎么區分SVG的title和HTML的title的不同呢?
將共同idea的元素分組在一起
在(X)html文件中,table,style和a元素由所需求的特殊規則管理,一些可能包含,一些可能不包含。
定義所需的規則都應該包括在同一個地方。
例如,我以XML為基礎的數據要有驗證規則,我要的是:
* 在同一個地方定義這些規則。
* 將這些特殊的規則和其他我(或者是別人)定義的規則集合區分。
命名空間是什么?
命名空間是唯一的URI。
這種格式的好處是任何傳輸XML的人,可以假裝成是拿到了域名(the bit after the http://, but before the next / 這句不知道怎么翻譯,希望有人指出,謝謝),但是依靠別人的域名并不好(特別是他們不知道你這樣做)。
在XML文檔里面,URI是和前綴聯系在一起的,每個元素用到的前綴表示著這個元素屬于哪個命名空間。例如:
[html]view plaincopy
rdf:description
xsl:template
zblsa:data
這些例子中:
* 冒號前面部分是前綴
* 冒號后面部分是本地部分
* 任何有前綴的元素是符合規范的名字
* 沒有前綴的元素是不符合規范的名字
我如何是用命名空間?
使用命名空間,首先將命名空間和URI聯系。
[html]view plaincopy
.
foo定義為元素標簽命名空間的前綴。xmlns作為前綴和該屬性連接,就像在命令“將這些字母和URI連接”。如一個不規范的文檔有兩個完全一樣的屬性,冒號后面部分能夠阻止相同的前綴同時被定義兩次。
定義一個命名空間前綴
這里有個定義一個命名空間前綴的例子:
[html]view plaincopy
An?example?document
a?simple?document
Another?element
所有的元素都在里面,命名空間前綴foo是和http://me.com/namespaces/foofoo聯系在一起的。
在同一命名空間定義多個前綴
不同的前綴代表不同的命名空間是可以的,如下:
[objc]view plaincopy
An?example?document
a?simple?document
Another?element
不同的命名空間定義相同的前綴
不同的命名空間定義相同的前綴也是可以的(不過不推薦),取決于上下文:
[html]view plaincopy
A?really?bad?idea
A?really?bad?idea
Hello?World
筆記:這不是一個好想法!
多個命名空間
如果你使用多個命名空間,那你無疑需要在同時使用多個命名空間——所以你該如何在同一時間聲明多個命名空間。
你需要做的就是使用多個xmlns聲明,就像這樣:
[html]view plaincopy
xmlns:bar="http://me.com/namespaces/foobar"
>
An?example?document
a?simple?document
Another?element
默認的命名空間
Q:使用任何命名空間時,所有元素都需要存在一個命名空間里面嗎。
A:是的,但是這樣不會有問題。
定義一個命名空間但是沒有和前綴聯系是允許的——在上面的例子中他們是不規范的名字。
這就是xhtml的重要性,作為這種語言的一種需求,xhtml不會取代html——html也不認識前綴們。
定義默認的命名空間,不用前綴,直接將xmlns分配就可以了:
[html]view plaincopy
舉例:
[html]view plaincopy
xmlns:bar="http://me.com/namespaces/foobar"
>
An?example?document
a?simple?document
Another?element
屬性和命名空間和我應該在命名空間URI最后放什么就不翻譯了。
再回到問題:
[html]view plaincopy
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee?http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
再結合W3C的教程:
XML Schema 是基于 XML 的 DTD 替代者。
XML Schema 描述 XML 文檔的結構。
XML Schema 語言也稱作 XML Schema 定義(XML Schema Definition,XSD)。
而DTD是,DTD(文檔類型定義)的作用是定義 XML 文檔的合法構建模塊。
歸根到底,命名空間的出現就是為了區分相同名字的元素他們有不同的含義。
通過命名空間就能區分究竟是你的還是我的元素:
xmlns:you= http://you 和 xmlns:me=http://me 這兩個不同的命名空間前綴。
如果是xmlns=uri,表示的是文檔默認的命名空間。
現在來看,W3C講得還是對的:
[html]view plaincopy
xmlns="http://java.sun.com/xml/ns/j2ee"
告訴schema認證器,XML中所有元素的命名空間都是http://java.sun.com/xml/ns/j2ee
[html]view plaincopy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi為前綴的命名空間。結合上面的例子,xsi:schemaLocation就是http://www.w3.org/2001/XMLSchema-instance/xsi:schemaLocation。
[html]view plaincopy
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee?http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
發現沒有,有兩個值,第一個為命名空間的值,第二個值為該命名空間使用的xml schema的位置,而由上面可知道:XML Schema 描述 XML 文檔的結構。
最后這個schema后面看書又補充了一些完整的內容進去。
引入xml schema 文檔
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
名稱空間的不同可以有兩種同名但不同的約束模式存在,
第一句并不能聲明schema所在的位置,只知道這是名稱空間的uri。
schemaLocation在公認的名稱空間中聲明,所以,前綴用到的時候,要加前綴xsi,同時聲明xsi對應的名稱空間。
schemaLocation屬性設置有兩個部分,名稱空間 空格 加上schema文件所在的位置。
不使用名稱空間引入schema文檔的話,只能引入一個。