你相信嗎?要將XML轉換格式不必寫程式。這一篇就大略地介紹XML的格式轉換。
要將XML轉換格式主要是使用XSLT (eXtensible Stylesheet Language Transformations)的技術,這是一個用來描述「如何抓取原資料並轉成新格式」的語言,而這語言也是XML的型式。這門技術由淺到深說來話長,在此我做一點簡單的示範和介紹。
一般格式轉換的做法大概像這樣:寫一隻程式 A 去資料庫抓資料後,產生 A 格式給A客戶;寫一隻程式 B 去資料庫抓資料庫抓資料後,產生 B 格式給供應商;再寫一隻程式 H 去資料庫抓資料庫抓資料後,產生 H 格式的網頁供網站顯示。
如果是 XML 的做法,大概像這樣:寫一隻程式 X 去資料庫抓資料後,產生一份XML;針對 A 格式準備一份 XSL 檔案 A;針對 B 格式準備一份 XSL 檔案 B;針對 H 格式網頁準備一份 XSL 檔案 H。接著再由工具程式,讀取 XML 和不同的 XSL 檔案,並產生不同的格式結果。
之前在[XML]04-資料交換格式那篇顯示的範例資料,其中的 H10/D10、UN/EDIFACT 和 ANSI X12 那三種資料格式,都不是我用手打的,而是用同一份 XML 資料加上三個不同的 XSL 檔案分別轉出來的。轉換的架構如下圖所示,說明如下:原始 XML 只有一份,XSL 1、XSL 2、 XSL 3則都是我寫的,目的是分別產生三種不同的格式。
至於那個工具程式只有一套,不用自己寫,如果是用程式開發,在各個程式語言平台都找得到這個工具程式而且是免費的。在這裡我用的是另一個更簡單的工具程式,就是瀏覽器。
由於瀏覽器本身就支援 XML 以及 XSL,所以如果只是一般的 XML 就照前面提過的顯示方式;如果當瀏覽器碰到有指定 XSL 的 XML 檔案時,就會自動進行轉換的動作並且顯示轉換後的結果。
講那麼多理論不如實際體會一下,以下是 XML 和 XSL 的資料,請將 XML 存一個檔案,XSL 存成另一個檔案,將兩個檔案放在同一個目錄下,然後用 IE 去開啟 XML 檔案,OK,很簡單吧。
XML 資料如下
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="myipo01.xslt"?>
<ipo:purchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ipo="http://www.altova.com/IPO" orderDate="2011-09-28" orderNumber="ORDNUM007" xsi:schemaLocation="http://www.altova.com/IPO
ipo.xsd">
<shipTo export-code="1" xsi:type="ipo:EU-Address">
<name>Helen Zoe</name>
<street>47 Eden Street</street>
<city>Cambridge</city>
<postcode>126</postcode>
</shipTo>
<billTo xsi:type="ipo:US-Address">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>AK</state>
<zip>95819</zip>
</billTo>
<Items>
<item partNum="811-AA">
<productName>Delicious Crab</productName>
<quantity>10</quantity>
<price>120.33</price>
<shipDate>2011-10-10</shipDate>
</item>
<item partNum="822-AA">
<productName>Funny Toys</productName>
<quantity>20</quantity>
<price>240.50</price>
<ipo:comment>Want this for the holidays!</ipo:comment>
<shipDate>2011-10-12</shipDate>
</item>
<item partNum="833-AA">
<productName>Lapis necklace</productName>
<quantity>30</quantity>
<price>128.99</price>
<ipo:comment>Go ahead. Make my day.</ipo:comment>
<shipDate>2011-10-15</shipDate>
</item>
</Items>
</ipo:purchaseOrder>
XSL 資料如下(注意檔名須為myipo01.xslt)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:n1="http://www.w3.org/2001/XMLSchema" xmlns:ipo="http://www.altova.com/IPO">
<xsl:template match="/">
<xsl:for-each select="ipo:purchaseOrder">
H10|<xsl:for-each select="@orderNumber"><xsl:value-of select="."/></xsl:for-each>|<xsl:for-each select="@orderDate"><xsl:value-of select="."/></xsl:for-each>|<BR/>
<xsl:for-each select="shipTo">H20|SHIPTO|
<xsl:for-each select="name">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="street">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="city">
<xsl:apply-templates/>
</xsl:for-each>|<BR/>
</xsl:for-each>
<xsl:for-each select="billTo">H20|BILLTO|
<xsl:for-each select="name">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="street">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="city">
<xsl:apply-templates/>
</xsl:for-each>|<BR/>
</xsl:for-each>
<xsl:for-each select="Items">
<xsl:for-each select="item">
D10|<xsl:for-each select="@partNum"><xsl:value-of select="." /></xsl:for-each>|
<xsl:for-each select="productName">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="quantity">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="price">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="ipo:comment">
<xsl:apply-templates/>
</xsl:for-each>|
<xsl:for-each select="shipDate">
<xsl:apply-templates/>
</xsl:for-each>|
<BR/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
如果你想觀察其中的差別,可以把 XML 檔案中第二列<?xml-stylesheet type="text/xsl" href="myipo01.xslt"?>刪掉後存檔,再用 IE 開啟 XML 檔案看看有什麼差別。
如果你想看看 XSL 長什麼樣子,可以看 myipo01.xslt 檔案的內容,甚至修改看看會有什麼變化。也許你會發現,XSL 沒有那麼難以了解和接近。