xml文件操作之XSLT


      最近接手的一個項目中數據的獲取通過數據庫與xml文件雙向處理,不知出入什么原因,該項目的先前設計者將數據從數據庫取出后又寫入到xml文件中,然后從xml文件中讀取數據。由於數據量大的原因,項目中幾個文件夾加載時瀏覽器一度崩潰,無賴只得對數據進行優化。本來sql server支持分頁與排序操作,起初我打算重寫這個存儲過程,但是之前的存儲過程之后發現代碼比較混亂,足有200多行的代碼,兵來將擋,一個上午的時間將先前的存儲過程重新整理修改支持了分頁自定義排序及搜索功能。本以為可以輕松,卻發現任有幾個文件夾不支持分頁功能,原來這些文件中的文件只從數據庫中取出部分數據,然后與xml文件交互后取出數據,多么蛋疼的事情,無賴只得找解決方案。網上搜索資料引出今天的主題——XSLT(EXtensible Stylesheet Language Transformations)。

      XSLT 在 1999 年 11 月 16 日被確立為 W3C 標准,現在幾乎所有的瀏覽器都支持XML和XSLT。XSLT 用於將一種 XML 文檔轉換為另外一種 XML 文檔,或者可被瀏覽器識別的其他類型的文檔,比如 HTML 和 XHTML。通常,XSLT 是通過把每個 XML 元素轉換為 (X)HTML 元素來完成這項工作的。通過 XSLT,您可以向或者從輸出文件添加或移除元素和屬性。您也可重新排列元素,執行測試並決定隱藏或顯示哪個元素,等等。

      下面進入正題如何使用XSLT:

       我們使用vs工具新建一個xslt文件,新建的文件中有如下默認代碼:

View Code
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl
="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

首先xslt文件也是一個xml文件,其語法同樣以<?xml version="1.0" encoding="utf-8"?>頭開始。

<xsl:stylesheet> 為xsl文件的根節點,也可使用<xsl:transform>。

xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 指向了官方的 W3C XSLT 命名空間。
version="1.0" 指定xsl文件的版本號。

<xsl:output method="xml" indent="yes"/> 定義輸出文本的格式。

<xsl:template> 元素用於構建模板。

match 屬性用於關聯 XML 元素和模板。match 屬性也可用來為整個文檔定義模板。match 屬性的值是 XPath 表達式(舉例,match="/" 定義整個文檔)。

......

XSLT的更多屬性:

元素 描述 IE N
apply-imports 應用來自導入樣式表中的模版規則。 6.0  
apply-templates 向當前元素或當前元素的子元素應用模板。 5.0 6.0
attribute 向元素添加屬性。 5.0 6.0
attribute-set 創建命名的屬性集。 6.0 6.0
call-template 調用一個指定的模板。 6.0 6.0
choose 與<when>以及<otherwise>協同使用,來表達多重條件測試。 5.0 6.0
comment 在結果樹中創建注釋節點。 5.0 6.0
copy 創建當前節點的一個備份(無子節點及屬性)。 5.0 6.0
copy-of 創建當前節點的一個備份(帶有子節點及屬性)。 6.0 6.0
decimal-format 定義當通過 format-number() 函數把數字轉換為字符串時,所要使用的字符和符號。 6.0  
element 在輸出文檔中創建一個元素節點。 5.0 6.0
fallback 假如處理器不支持某個XSLT元素,規定一段備用代碼來運行。 6.0  
for-each 遍歷指定的節點集中的每個節點。 5.0 6.0
if 包含一個模板,僅當某個指定的條件成立時應用此模板。 5.0 6.0
import 用於把一個樣式表中的內容倒入另一個樣式表中。 6.0 6.0
include 把一個樣式表中的內容包含到另一個樣式表中。 6.0 6.0
key 聲明一個命名的鍵。 6.0 6.0
message 向輸出寫一條消息(用於錯誤報告)。 6.0 6.0
namespace-alias 把樣式表中的命名空間替換為輸出中不同的命名空間。 6.0  
number 測定當前節點的整數位置,並對數字進行格式化。 6.0 6.0
otherwise 規定 <choose> 元素的默認動作。 5.0 6.0
output 定義輸出文檔的格式。 6.0 6.0
param 聲明一個局部或全局參數。 6.0 6.0
preserve-space 用於定義保留空白的元素。 6.0 6.0
processing-instruction 生成處理指令節點。 5.0 6.0
sort 對結果進行排序。 6.0 6.0
strip-space 定義應當刪除空白字符的元素。 6.0 6.0
stylesheet 定義樣式表的根元素。 5.0 6.0
template 當指定的節點被匹配時所應用的規則。 5.0 6.0
text 通過樣式表生成文本節點。 5.0 6.0
transform 定義樣式表的根元素。 6.0 6.0
value-of 提取選定節點的值。 5.0 6.0
variable 聲明局部或者全局的變量。 6.0 6.0
when 規定 <choose> 元素的動作。 5.0 6.0
with-param 規定需被傳入某個模板的參數的值。 6.0 6.0

下面用具體的實例來說明xslt的用法:

book.xml文件:

View Code
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="book.xslt"?>
<books>
<book>
<title>C#</title>
<description>C#開發寶典</description>
<price>85</price>
</book>
<book>
<title>java</title>
<description>java開發寶典</description>
<price>78</price>
</book>
<book>
<title>php</title>
<description>php開發寶典</description>
<price>33</price>
</book>
<book>
<title>C</title>
<description>C語言開發寶典</description>
<price>95</price>
</book>
</books>

我們使用book.xslt將book.xml文件轉換成瀏覽器可讀文件,book.xslt:

View Code
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl
="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="books">
<html>
<head>MY book</head>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>title</th>
<th>description</th>
<th>price</th>
</tr>

<xsl:for-each select="book">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="description"/>
</td>
<td>
<xsl:value-of select="price"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

使用<?xml-stylesheet type="text/xsl" href="book.xslt"?>在book.xml文件中關聯book.xslt文件在瀏覽器中瀏覽結果:

解析:

<xsl:for-each> 元素可用於選取指定的節點集中的每個 XML 元素。

<xsl:value-of> 元素用於提取某個選定節點的值,並把值添加到轉換的輸出流中。

select 屬性的值是一個 XPath 表達式。此表達式的工作方式類似於定位某個文件系統,在其中正斜杠可選擇子目錄。

 

 xmlt高級應用:

    以上介紹了如何將一個xml文件轉換成為(x)html,下面看看xslt的高級用法。

    <xsl:if> 元素用於針對 XML 文件的內容放置一個條件測試。

    <xsl:choose> 元素被用來與 <xsl:when> 和 <xsl:otherwise> 配合使用,來表達多重的條件檢驗。

   如:

View Code
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl
="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="books">
<html>
<head>MY book</head>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>title</th>
<th>description</th>
<th>price</th>
</tr>
<xsl:for-each select="book">
<xsl:if test="price &gt; 60">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="description"/>
</td>
<xsl:choose>
<xsl:when test="price &gt; 90">
<td bgcolor="#FFFFF">
<xsl:value-of select="price"/>
</td>
</xsl:when>
<xsl:otherwise>
<td bgcolor="#FOOFF">
<xsl:value-of select="price"/>
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

瀏覽器中查看:

 

   <xsl:sort> 元素用於對輸出進行排序。

View Code
<xsl:for-each select="book">
<xsl:sort select="price" order="ascending"/>
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="description"/>
</td>
<td>
<xsl:value-of select="price"/>
</td>
</tr>
</xsl:for-each>

瀏覽結果:

 

<xsl:apply-templates> 元素可把模板規則應用到當前節點或者當前元素的子節點。

下面用一個實例來講xsl:apply_templates的用法及xslt分頁:

xslt文件:

View Code
<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" media-type="text/plain"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="//Lines">
<xsl:element name="Lines">
<xsl:apply-templates select="//Lines/Line" >
<xsl:sort select="@FieldName" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>

<xsl:template match="//Lines/Line">
<xsl:if test="ceiling(position() div 50) = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

xml文件過大不便全部貼出,這里只貼出格式:

View Code
<Lines>
<Line FieldID="559" FieldCode="" FieldName="Zip/Postal Code" FieldDesc="Zip / Postal Code" FieldTypeID="6" FieldTypeName="Text" CreatorID="-" CreatorName="-" StatusID="1" StatusDesc="Enabled" CategoryID="11" CategoryName="-" EntityID="4" EntityName="-" CreateDate="-" SystemField="0" FilledBy="Applicant" SystemFieldDesc="N" Required="0" RequiredDesc="N" TypeID="1" IsEdit="1" IsHRIS="0" Chk="" Parse="N" />
<Line FieldID="540" FieldCode="" FieldName="Specialized SkillsAccounting" FieldDesc="Specialized Skills Please specify if you are specialized in any accounting skills" FieldTypeID="6" FieldTypeName="Text" CreatorID="-" CreatorName="-" StatusID="1" StatusDesc="Enabled" CategoryID="11" CategoryName="-" EntityID="4" EntityName="-" CreateDate="-" SystemField="0" FilledBy="Applicant" SystemFieldDesc="N" Required="0" RequiredDesc="N" TypeID="1" IsEdit="1" IsHRIS="0" Chk="" Parse="N" />
。。。。。。
</Lines>

 

XSLT在客戶端應用

      在瀏覽器中把 XML 轉換為 XHTML,我們使用javascript來轉換:

View Code
<div>
<script type="text/javascript">
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async
= false;
xml.load(
"book.xml");

var xsl = new ActiveXObject("Microsoft.XMLDOM");
xsl.async
= false;
xsl.load(
"book.xslt");

document.write(xml.transformNode(xsl));
</script>
</div>

      第一段代碼創建了微軟的 XML 解析器的一個實例,然后把 XML 文件載入了內存。第二段代碼創建了解析器的另一個實例,然后把這個 XSL 文件載入了內存。最后一行代碼使用 XSL 文檔轉換了 XML 文檔,並在瀏覽器中把結果作為 XHTML 顯示出來。任務完成!

本人也是xslt初學者,文章中有錯誤之處請諒解,歡迎提出修改意見,謝謝!

 

注:本文為作者原創,歡迎轉載,轉載請注明出處:www.cnblogs.com/aces


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM