2010年8月26日 星期四

一個練習XSLT的網站

XSL(eXtensible Stylesheet Language)是XML在用的樣式表
一般而言,XML只是單純的文字文件
但是透過XSL可以將所設定的文字樣式(大小、字型、背景...)套用到XML文件裡面
使XML的文件呈現出不一樣的風格

XSLT則是將XML的文件轉換格式,例如轉成HTML檔
只要準備好兩份檔案:XML文件以及XSL文件
就可透過轉換程式來轉檔

我看的書是介紹使用xalan這套程式來轉
但是我下載安裝遇到一些問題

後來在網路上發現這個網站
XSLT Tryit Editor v1.0
可以幫助我們做XSLT的驗證

2010年8月22日 星期日

什麼是 DTD (Document Type Definition)

XML提供了兩種文件的驗證機制,一個是DTD,另一個則是XML Schema
雖然目前的主流是使用XML Schema來驗證文件
我想還是盡量多了解一下DTD
並且把我所知道的部分做成筆記

DTD ( 文件類型定義, Document Type Definition),我把整個機制的重點放在Definition.
是用來訂出文件合法的區塊,也就是把元素的架構寫出來
語法<!DOCTYPE root-element [element-declarations]>
以上敘述有點難懂,還是來看一下範例

<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE comic-list [
    <!ELEMENT comic-list (entry+)>
    <!ELEMENT entry       (author, title, rating)>
    <!ELEMENT author    (#PCDATA)>
    <!ELEMENT title         (#PCDATA)>
    <!ELEMENT rating     (#PCDATA)>
]>
<comic-list>
<entry>
     <author>井上雄彥</author>
      <title>灌籃高手</title>
      <rating>普遍級</rating>
</entry>
</comic-list>

從這邊可以看出entry這個父元素包含著author, title跟rating這些子元素
這就是這個元素區塊的架構
若是之後要再加入其他的漫畫列表
就必須照著DTD所定義的規範來依序加入entry, 且entry下面的子元素(author, title, rating)必須照順序來寫,另外,entry下面還要補上+或*號,表示這個檔案裡面有多筆entry, DTD也會依此來驗證此文件是否符合規定,大家都照規定來,一份完整且嚴謹的XML文件就可以互相使用

重新提醒一下, !DOCTYPE下面一定接根元素 (root element)
!DOCTYPE下面的第一行!ELEMENT也一定是根元素開頭
接下來再來定義根元素下面有幾個子元素,並且用括號()來刮起來
之後再來個別宣告子元素的type,像是(#PCDATA)之類的
若是該子元素又包著另一層的子元素
則不需宣告type,但要註明底下包著哪些子元素

譬如說

<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE comic-list [
    <!ELEMENT comic-list (entry+)>
    <!ELEMENT entry       (author, title, rating)>
    <!ELEMENT author    (firstname, lastname)>
    <!ELEMENT firstname (#PCDATA)>
    <!ELEMENT lastname (#PCDATA)>
    <!ELEMENT title         (#PCDATA)>
    <!ELEMENT rating     (#PCDATA)>
]>


最上面的範例是從XML文件內宣告DTD的架構
還有另一種寫法是從外部文件內宣告
我將範例改寫如下


<?xml version="1.0" encoding="Big5"?>
<!DOCTYPE comic-list SYSTEM "comic-list.dtd"
<comic-list>
<entry>
     <author>井上雄彥</author>
      <title>灌籃高手</title>
      <rating>普遍級</rating>
</entry>
</comic-list>
接著再另外寫一份DTD的文件 (comic-list.dtd)好讓上述的XML文件讀取

<?xml version="1.0">
<!EEMENT comic-list (entry)>
<!ELEMENT entry       (author, title, rating)>
<!ELEMENT author    (#PCDATA)>
<!ELEMENT title         (#PCDATA)>
<!ELEMENT rating     (#PCDATA)>
這樣就是透過外部DTD來驗證XML文件架構的機制

以另一種觀點來看,DTD可以視為一種協議,不同的使用者可以透過共同訂制的DTD來交換資料,應用程式也可以透過DTD來驗證所接收的XML文件是否為有效的文件

參考資料: 1. Introduction to DTD
                  2. DTD tutorial

2010年8月20日 星期五

URI、URL和URN

URI的全名是Uniform Resource Identifier,用來識別某項資源

URL就是網址,在網路上經過註冊,一個獨一無二的地址

URN則是Uniform Resource Name, 我這邊把URN當成某項資源的名稱,且該名稱也是獨一無二
例如ISBN 0486275574 (urn:isbn:0-486-27557-4),透過這個ISBN,我們可以在網路上找到這本書是莎士比亞的羅密歐與茱麗葉
書籍在出版的時候,都會有ISBN象徵自己的代號,這就是URN的例子
總歸來說,URL跟URN屬於URI的集合

前一篇我們提到名稱空間(namespace)
最後舉了一個範例



<?xml version="1.0" encoding="Big5"?>
<comic-list xmlns:ct="content"
                    xmlns:qa="quality">
   <entry>
      <author>井上雄彥</author>
      <title>灌籃高手</title>
      <ct:rating>普遍級</ct:rating>
      <qa:rating>5 stars</qa:rating>
   </entry>
   <entry>
       <author>井上雄彥</author>
      <title>浪人劍客</title>
      <ct:rating>限制級</ct:rating>
      <qa:rating>5 stars</qa:rating>
    </entry>
</comic-list>

我提到了xmlns:ct="content"
雙引號裡面的內容是名稱空間的名字
按照一般的用法習慣,該名稱應該要是一個URI
代表我這份文件所用的元素命名,在這個世界上不會跟其他人衝到
所以大家最常用的就是使用URL (URL也是URI的一種)
譬如說我將以上的範例改寫成

<?xml version="1.0" encoding="Big5"?>
<comic-list xmlns:ct="http://ericchiu-xml.blogspot.com/content"
                    xmlns:qa="http://ericchiu-xml.blogspot.com/quality">
   <entry>
      <author>井上雄彥</author>
      <title>灌籃高手</title>
      <ct:rating>普遍級</ct:rating>
      <qa:rating>5 stars</qa:rating>
   </entry>
   <entry>
      <author>井上雄彥</author>
      <title>浪人劍客</title>
      <ct:rating>限制級</ct:rating>
      <qa:rating>5 stars</qa:rating>
    </entry>
</comic-list>

當我把這份XML文件發布到網路上,別人覺得有用處,想要結合我的資料來做一個漫畫系統查詢
因為我用了URI當作名稱空間,就可以避免別人跟我取到相同的元素名稱(<ct:rating>以及 <qa:rating>)
電腦在識別文件上也不會產生問題了

什麼是名稱空間(Name Spaces)


關於Namespaces這個名詞,對我來說實在是不好理解
查了一些資料後,總算有一些初步的認識

根據W3C的定義:
[Definition: An XML namespace is identified by a URI reference [RFC3986]; element and attribute names may be placed in an XML namespace using the mechanisms described in this specification. ]

之所以會有名稱空間的出現,是為了解決元素名稱重複的問題
其實XML的namespace就是一項識別XML元素的機制
假設A君正在寫漫畫分類的xml文件
以下是簡單的範例:
<?xml version="1.0" encoding="Big5"?>
<comic-list>
   <entry>
       <title>灌籃高手</title>
       <rating>普遍級</rating>
   </entry>
   <entry>
      <title>浪人劍客</title>
      <rating>限制級</rating>
   </entry>
</comic-list>

而B君也寫了相同的文件,但分類的方式不一樣

<?xml version="1.0" encoding="Big5"?>
<comic-list>
   <entry>
      <author>井上雄彥</author>
      <title>灌籃高手</title>
      <rating>5 stars</rating>
   </entry>
   <entry>
      <author>井上雄彥</author>
      <title>浪人劍客</title>
      <rating>5 stars</rating>
   </entry>
</comic-list>

當我們試著將這兩份文件合併時,電腦判讀就會出現問題

<?xml version="1.0" encoding="Big5"?>
<comic-list>
   <entry>
      <author>井上雄彥</author>
      <title>灌籃高手</title>
      <rating>普遍級</rating>
       <rating>5 stars</rating>
   </entry>
   <entry>
      <author>井上雄彥</author>
      <title>浪人劍客</title>
      <rating>限制級</rating>
      <rating>5 stars</rating>
    </entry>
</comic-list>

電腦不知道讀取rating這個元素時,代表的到底是內容分級、還是評價分級
所以我們可以在元素前面加入前置詞(prefix),來解決判讀的問題


<?xml version="1.0" encoding="Big5"?>
<comic-list>
   <entry>
      <author>井上雄彥</author> 
      <title>灌籃高手</title>
      <content-rating>普遍級</content-rating>
      <quality-rating>5 stars</quality-rating>
   </entry>
   <entry>
      <author>井上雄彥</author>
      <title>浪人劍客</title>
      <content-rating>限制級</content-rating>
      <quality-rating>5 stars</quality-rating>
    </entry>
</comic-list>


另一個解決的方式就是使用名稱空間:
<?xml version="1.0" encoding="Big5"?>
<comic-list xmlns:ct="content"
                    xmlns:qa="quality">
   <entry>
      <author>井上雄彥</author> 
      <title>灌籃高手</title>
      <ct:rating>普遍級</ct:rating>
      <qa:rating>5 stars</qa:rating>
   </entry>
   <entry>
      <author>井上雄彥</author>
      <title>浪人劍客</title>
      <ct:rating>限制級</ct:rating>
      <qa:rating>5 stars</qa:rating>
    </entry>
</comic-list>

上述xmlns:稱為宣告namespace的關鍵字
而雙引號" "裡面的單字則是該名稱空間的名字
至於上述的ct以及qa則是別名,也可以說是名稱空間的前置詞(prefix)
代表它們所屬名稱空間的縮寫

名稱空間的使用有助於認證一份XML文件裡面的元素是獨一無二的

相關資料參考來源:

2010年8月17日 星期二

XML的註解寫法

若是要在XML裡面插入註解,只需利用"<!--"和"-->"即可
電腦會忽略符號裡面的文字敘述
例如:<!-- 此份文件出自於http://ericchiu-xml.blogspot.com/ -->

有一點必須注意:
我們不可以在標記中加入註解
像 <name <!-- add a name tag here -->>ericchiu</name>
註解必須出現在標示符號的前面或後面

空元素、子元素、父元素和根元素

只要是不包含內容的元素,就稱為空元素 (empty elements)
通常空元素都會包含屬性 (但並非必要)

以下是最常見的空元素寫法
<email href="mailto:ericchiu@blogggger.com></email>
--> 兩個<>之間並沒有字元資料 (data character)存在

空元素還有一種簡化的寫法,就是利用</>,將起始標記跟結尾標記合而為一
像是<email href="mailto:ericchiu@blogggger.com/>
對於XML而言,以上兩種空元素是一樣的

XML文件的資料結構,是由元素所組成的樹狀結構,其樹狀的元素可以重複,高度沒有限制
以一個簡單的XML文件為例
<?xml version="1.0"?>
<menu>
   <french>
      <chicken>french chicken</chicken>
   </french>
   <england>
      <chicken>english chicken</chicken>
   </england>
   <chinese>
      <chicken>chinese chicken</chicken>
   </chinese>
</menu>

被其他元素所包含住的,稱為子元素,例如範例的chicken
包含了子元素的元素,則稱為父元素,例如french, england, chinese
根元素位於文件中的頂端(Top)
所有XML文件都必須具備一個唯一的根元素 (例如本範例中的menu)
在撰寫XML文件時,若是沒有一個唯一的根元素存在
是會被視為語法錯誤的
以下是不符合此原則所產生出來的錯誤訊息



無法顯示 XML 網頁

XML 文件只允許一個最上層元件

關於XML的元素、屬性以及起始與結尾標記

以下列語法為例
<cost>199.00</cost>
其中cost稱為標籤裡面的"元素" (element)
在cost前後加上<>,就稱為資料的起始標記 (start tag)
在cost前後加上</>,則稱為資料的結尾標記 (end tag)

所以說"元素"是構成一份XML文件很重要的單位
每一個元素的前後都會由起始標記 (start tag) 和結尾標記 (end tag)來做區隔

由於XML嚴格的語法,規定起始標記跟結尾標記必須同時存在
例如<cost>199.00就會被視為錯誤的XML語法
(正確的語法為<cost>199.00</cost>)
相比起來HTML在這方面的規定就寬鬆多了

之前的文章提過
XML有一項特點就是沒有事先定義的標籤 (No predefined tag)
所以必須由作者本身來建立文件裡面的每一個元素
作者只需加入自己所需要的元素即可
充分展現了XML可擴充的特性

接下來談談屬性 (attributes)
XML可以透過屬性來替元素加入額外的資訊
屬性有自己的名稱(name)以及屬性值(value)
根據定義
屬性是加在起始標記裡面
起始標記可以不包含,或包含一個以上的屬性
屬性名稱跟屬性值之間利用等號來相連
屬性值前後必須加上單引或雙引號

請看以下範例會比較清楚
<tel preferred="true">3345678</tel>
tel是元素
preferred是屬性名稱
"true"是屬性值
要注意的是屬性名稱並非元素名稱的一部分
所以結尾符號才會只有</tel>而非</tel preferred="true">