原文:https://blog.csdn.net/lengxiao1993/article/details/77914155
Maven 是一個 java 開發人員很難繞過的構建工具, 因為有眾多的開源項目都使用 Maven 作為其構建工具。 而閱讀 maven 中的 pom 文件, 是了解一個項目依賴關系和構建方式的重要環節。 但是 pom 文件的頭部會讓初學者感到困惑, 這里對其進行一個清晰易懂的解釋(梳理自網絡資料)
先修知識
- 理解 xml 中的標簽含義, 及標簽之間樹狀的嵌套結構
- 了解 pom ( project object model)文件
POM 文件頭示例
-
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
初學者看到如上的內容應當有如下困惑點:
-
xmlns:xsi
,xmlns
,xsi:schmeLocation
這些看上去相近的屬性是什么含義, 為什么他們的值是不一樣的 URL
從 xmlns 的作用講起
一個 xml 文檔中如果包含如下兩種定義不同, 但是名稱相同的元素, xml 解析器是無法解析的, 因為它不能確定當你調用 document.getElementsByTagName("book")
時應該返回哪個元素。
-
<!-- 這里的 table 元素描述的是一個表格--> <table> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table> <!-- 這里的 table 元素描述的是一個家居桌子--> <table> <name>African Coffee Table</name> <width>80</width> <length>120</length> </table>
顯然, 如果給他們的名字添加一個前綴, 則命名沖突的問題就可以解決。
-
<!-- 這里的 table 元素描述的是一個表格--> <h:table> <!--添加了前綴 h --> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> <!-- 這里的 table 元素描述的是一個表格--> <f:table> <!--添加了前綴 f --> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table>
但是, 在一個擁有眾多元素的文檔中, 僅僅擁有前綴, 也不能完全避免命名沖突的問題。
- 注意 xml 文檔相互之間是可以通過 XInclude, External Entites 實現相互包含或者引用的。
此時, 命名空間就誕生了, 我們可以為元素定義一個命名空間, 將一個很長的, 可以保證全局唯一性的字符串與該元素關聯起來。這樣就可以避免命名沖突了。
但是如何保證那個較長的字符串全局唯一呢, 最好的方式莫過於使用 統一資源標識符(Uniform Resource Identifier,URI) 了, 而我們最常見的 URI 就是平時經常訪問的網址 URL 了。
xmlns:namespace-prefix="namespaceURI"
應用到我們所舉的例子中就是:
-
<!-- 這里的 table 元素描述的是一個表格--> <h:table xmlns:h="http://www.w3.org/TR/html4/"> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table> <!-- 這里的 table 元素描述的是一個表格--> <f:table xmlns:f="http://www.w3school.com.cn/furniture"> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table>
- 所以, 對於命名空間的標識符, URI 的作用僅僅是保證唯一性, 它並不需要對應一個可以訪問的資源或文件 ! 但是, 有很多公司都會讓 namespace 的 URI 指向一個包含該命名空間信息的網頁
回到我們的 POM 文檔頭中,你會發現 project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
中的http://www.w3.org/2001/XMLSchema-instance可以訪問到一個正常的頁面, 但是如果訪問 xmlns="http://maven.apache.org/POM/4.0.0"
中的 http://maven.apache.org/POM/4.0.0 就會得到一個 PAGE NOT FOUND 錯誤, 頁面未獲取到。
xmlns 出現在沒有沒有前綴的元素中的含義
-
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
細心的童鞋會注意到, project 元素前面並沒有前綴。 這里實際上使用的是默認命名空間(default naming space)。 它的語法如下:
<elementName xmlns="namespaceURI">
例如我們的 project 元素定義 和下面的例子
<table xmlns="http://www.w3.org/TR/html4/"> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table>
使用默認命名空間的作用是, 該元素內部的子元素都會默認屬於該命名空間下, 我們不需要為他們一一添加命名空間前綴。
xmlns:xsi 與 xsi:schemaLocation
現在來看文件頭中剩下的, 看上去更為復雜的部分。
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
根據之前的知識我們可以理解, xmlns:xsi
定義了一個命名空間前綴 xsi
對應的唯一字符串 http://www.w3.org/2001/XMLSchema-instance
。 但是讀者會發現, 這個 xmlns:xsi
在不同的 xml 文檔中似乎都會出現。 這是因為, xsi
已經成為了一個業界默認的用於 XSD((XML Schema Definition) 文件的命名空間。 而 XSD 文件(也常常稱為 Schema 文件)是用來定義 xml 文檔結構的。
- 注解: XML 解析器可以根據 一個 XSD 文件的內容來解析另一個 XML 文件, 判斷該文件的結構是否和 XSD 文件中定義的一致。 XSD 文件 可以理解為 XML 文檔可以自定義的語法或格式檢查器。
那么, 有了上述的理解, 再來看
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
上面這行的語法其實是, xsi:schemaLocation = "鍵" “值”
即 xsi 命名空間下 schemaLocation 元素的值為一個由空格分開的鍵值對。
-
前一個“鍵” http://maven.apache.org/POM/4.0.0 指代 【命名空間】, 只是一個全局唯一字符串而已
-
后一個值指代 【XSD location URI】 , 這個值指示了前一個命名空間所對應的 XSD 文件的位置, xml parser 可以利用這個信息獲取到 XSD 文件, 從而通過 XSD 文件對
所有屬於 命名空間 http://maven.apache.org/POM/4.0.0 的元素結構進行校驗, 因此這個值必然是可以訪問的, 且訪問到的內容是一個 XSD 文件的內容