XML相關知識全接觸(一)

黃博文發表於2013-10-14

XML相關知識全接觸(一)

XML檔案格式已經出來很久了。他的風頭如今在JSON、YAML等新興檔案格式的衝擊下已經顯的不那麼強勁。但是XML仍然是當今世界上使用最廣泛的檔案格式。圍繞著它也有一大堆的概念和知識點。所以我們還是很有必要全面瞭解下。

XML

XML全稱為eXtensible Markup Language,即可擴充套件標記語言。其被設計用來傳輸及儲存資料。

XML與HTML看似比較相似,但是其設計目的並不相同。

  • XML用來傳輸及儲存資料,主要關注資料是什麼。

  • HTML用來顯示資料,主要關注資料看起來是什麼樣。

  • HTML的tag是預定義的,比如說table標籤,瀏覽器會知道它是什麼含義。

  • XML的tag不是預定義的,需要自己設計tag並描述tag的含義。XML中的tag如果不借助XSLT檔案,瀏覽器只會以簡單的文字方式展示。

很多人認為HTML是XML檔案的一個子集。其實這種觀點是錯誤的,因為HTML的實現並未嚴格遵循XML的語法。比如XML要求每個tag必須要有閉合標記,XML的tag是大小寫敏感的,XML給tag新增的屬性必須要使用引號包起來…這些語法要求HTML都不滿足。

請看XML的一個示例。

book.xml
1
2
3
4
5
6
7
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
    <name>Effective JavaScript</name>
    <category>Program Language</category>
    <author>Bowen</author>
    <description>This book is about JavaScript Language.</description>
</book>

這是一個簡單的XML檔案。第一行說明了xml的版本及編碼型別。接下來是一個根節點book,根節點可以包含很多子節點。

XML名稱空間

由於XML的tag並不像HTML那樣是預定義的,那麼很有可能兩個XML中的同名tag具有不同的含義。那麼在合併XML等操作時勢必會造成衝突。解決的辦法就是給XML的tag加上名稱空間(即namespace),每一個namespace都可以指定一個字首。這些字首會區分同名tag。

假設這裡有另一個xml檔案。

anotherBook.xml
1
2
3
4
5
6
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
    <name>Rework</name>
    <page>120</page>
    <publishDate>2013-10-08</publishDate>
</book>

如果我們要合併這兩個xml節點到同一個xml檔案中時,不加namespace會發生衝突,因為含有同名的tag,其子節點的結構並不相同。接下來我們給其加上名稱空間併合並。

combined.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<root>
<ns1:book xmlns:ns1="http://www.huangbowen.net/ns1">
    <ns1:name>Effective JavaScript</name>
    <ns1:category>Program Language</category>
    <ns1:author>Bowen</author>
    <ns1:description>This book is about JavaScript Language.</description>
</book>

<ns2:book xmlns:ns2="http://www.huangbowen.net/ns2">
     <ns2:name>Rework</name>
    <ns2:page>120</page>
    <ns2:publishDate>2013-10-08</publishDate>
     </book>
</root>

xmlns是xml namespace的縮寫。引號後面是tag的字首。這個字首可以省略,比如xmlns="http://www.huangbowen.net/ns1",相當於沒有字首的tag自動應用預設的名稱空間。需要注意的是名稱空間的URI只是給名稱空間提供一個唯一的標識,xml解析器並不會訪問這個URI來獲取任何資訊。很多公司習慣將這個URI一個web頁面,該web頁面描述了該namespace的相關資訊。

XSD

XSD全稱為XML Schema Definition,即XML結構定義語言。每個XSD檔案是對一個XML檔案的結構定義。 由於XML中的tag並不是預定義的,那麼每人都可以建立自己的XML結構文件。如果你想讓別人按照你的標準建立一份xml檔案,你可以使用XSD檔案來描述你的標準。

這是針對本文示例book.xml檔案的一個XSD檔案。

book.xsd
1
2
3
4
5
6
7
8
9
10
11
12
13
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="book">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="name"/>
                <xs:element type="xs:string" name="category"/>
                <xs:element type="xs:string" name="author"/>
                <xs:element type="xs:string" name="description"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

從上可以看出其實XSD檔案本身就是一個XML檔案,它遵循XML語法,比如每個tag都需要有結束標記,必須有且只有一個根節點等。

在一個XML檔案中可以新增其Schema的引用資訊。

book.xml
1
2
3
4
5
6
7
<?xml version="1.0" encoding="ISO-8859-1"?>
<ns1:book xmlns:ns1="http://www.huangbowen.net/ns1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:targetLocation="http://www.huangbowen.net/book.xsd">
    <ns1:name>Effective JavaScript</name>
    <ns1:category>Program Language</category>
    <ns1:author>Bowen</author>
    <ns1:description>This book is about JavaScript Language.</description>
</book>

在IDE中,如果你的XML節點沒有遵守你引用的Schema中的定義,就會給出錯誤提醒。

XSLT

XSLT全稱為EXtensible Stylesheet Language Transformations。 XSLT用於將XML文件轉換為XHTML或其他XML文件。

在講XSLT之前我們先講講XSL。XSL全稱為Extensible Stylesheet Language,即可擴充套件樣式表語言。眾所周知,CSS是HTML檔案的樣式表,而XSL則是XML檔案的樣式表。XSL檔案描述了XML檔案應該如何被顯示。

其實XSL不僅僅是樣式表語言,它主要包含3部分:

  • XSLT - 用來轉換XML文件

  • XPath - 查詢和操作XML文件中的節點

  • XSL-FO - 格式化XML文件

XSLT使用XPath來查詢XML中的元素。

XSLT通過一個xml檔案來定義源xml檔案與目標檔案之間的轉換關係。該xml檔案必須以<xsl:stylesheet><xsl:transform>作為根節點。

對於本文的示例book.xml,如果我們使用瀏覽器開啟顯示效果如下。

XML相關知識全接觸(一)

現在我們建立一個XSLT檔案將其轉換為一個HTML檔案。

book.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My Book</h2>
  <table border="1">
    <tr>
      <td>name</td>
      <td><xsl:value-of select="book/name" /></td>
    </tr>
    <tr>
      <td>category</td>
      <td><xsl:value-of select="book/category" /></td>
    </tr>
    <tr>
      <td>author</td>
      <td><xsl:value-of select="book/author" /></td>
    </tr>
    <tr>
      <td>description</td>
      <td><xsl:value-of select="book/description" /></td>
    </tr>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

然後我們在book.xml檔案中加入對這個XSLT檔案的引用。

book.xml
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="book.xsl"?>
<book>
    <name>Effective JavaScript</name>
    <category>Program Language</category>
    <author>Bowen</author>
    <description>This book is about JavaScript Language.</description>
</book>

接下來我們再用瀏覽器開啟book.xml檔案,發現顯示變成了這樣。是不是很神奇?

XML相關知識全接觸(一)

注意如果你使用chrome開啟該book.xml檔案,請設定chrome的--allow-file-access-from-files屬性,這樣chrome才允許載入本地的xsl檔案。解決方案看這裡:http://stackoverflow.com/questions/3828898/can-chrome-be-made-to-perform-an-xsl-transform-on-a-local-file

OK,這篇文章講的夠多了,下篇接著講XPath,XML to Object以及XML文件格式與近來風頭強勁的JSON、YAML格式的比較。