基於xslt的簡單應用開發
一.本文所涉及的內容
- 本文所涉及的內容
- xslt及其應用場景
- 簡單應用示例
- 轉換示例:通過xslt將xml轉換成html
- 基本語法應用示例:變數,迴圈,條件,模板(方法),引數等
- 伺服器端轉換方式-結合c#進行方法擴充套件
- 繼承(匯入)和過載(重定義)的應用
二.xslt及其應用場景
XSLT可擴充套件樣式錶轉換語言(Extensible Stylesheet Language Transformations)是一種對XML文件進行轉化的語言,它的作用相當於就是樣式表(css)之於HTML檔案,XSLT中的T代表英語中的“轉換”(transformation)。它是XSL(Extensible stylesheet language)規範的一部分。
常用應用場景如下:
第一,將源xml轉換成符合要求的xml、HTML。例如某企業應用介面提供的資料為較為冗餘的xml,可以按需使用xslt將源xml進行精簡轉換成xml或者HTML,同時如果資料來源變化的話,只需要對應的調整xstl轉換檔案即可。
第二,搜尋引擎抓取的HTML解析。此類特點是該抓取的html的格式多樣而且非固定,可使用xslt進行解析成標準格式再進行入庫索引,如果html格式有變化,對應修改xslt模板即可。
XSLT 是如何工作的:
a)首先XML文件被讀入記憶體當中並存儲為棵結點樹
b)<xsl:template match=“/”> 模板用來選擇整個樹的根結點
c)模板中的規則被用來進行結點的匹配從而改變XML 樹的結構
d)如果還有其它模板,那麼它們必須顯示地從主模板中呼叫 如果還有其它模板,那麼它們必須顯示地從主模板中呼叫
e)XML 樹中沒有匹配的部分保持原來的狀態不變
f)模板應用完成後,樹被作為一個新的文字文件輸出出來
(更多請Google XSLT)
三.簡單應用示例
轉換示例1.通過xslt將xml轉換成html,通過瀏覽器轉換的方式
xml資料來源檔案:<?xml version="1.0" encoding="UTF-8"?> <!--客戶端轉換的xslt--> <?xml-stylesheet type="text/xsl" href="XSLT_Client.xslt"?> <books> <book> <title>HTML5+CSS3從入門到精通(附1DVD)</title> <author>李東博</author> <publisher>清華大學出出版社</publisher> <price>42.90</price> <year>2015</year> </book> <book> <title>安全之路——Web滲透技術及實戰案例解析(第2版)</title> <author>陳小兵</author> <publisher>電子工業出版社</publisher> <price>84.90</price> <year>2015-09-1</year> </book> </books>
客戶端轉換使用的xlst檔案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
<xsl:template match="/">
<xsl:variable name="paraPath" select="/books/book" ></xsl:variable>
<html>
<body>
<h2>Books List</h2>
<table border="1">
<tr bgcolor="#87CEFA">
<th align="left">Title</th>
<th align="left">author</th>
<th align="left">publisher</th>
<th align="left">price</th>
<th align="left">year</th>
</tr>
<xsl:for-each select="$paraPath">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="author"/>
</td>
<td>
<xsl:value-of select="publisher"/>
</td>
<td>
<xsl:value-of disable-output-escaping="yes" select="price"/>
</td>
<td>
<xsl:value-of select="year"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
轉換的結果如下: Books List
Title | author | publisher | price | year |
---|---|---|---|---|
HTML5+CSS3從入門到精通(附1DVD) | 李東博 | 清華大學出出版社 | 42.90 | 2015 |
安全之路——Web滲透技術及實戰案例解析(第2版) | 陳小兵 | 電子工業出版社 | 84.90 | 2015-09-1 |
2.通過xslt將xml轉化成html,通過伺服器端轉換的方式
xml資料來源檔案(不需要把xslt檔案連結到xml當中):
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<title>HTML5+CSS3從入門到精通(附1DVD)</title>
<author>李東博</author>
<publisher>清華大學出出版社</publisher>
<price>42.90</price>
<year>2015</year>
</book>
<book id="2">
<title>安全之路——Web滲透技術及實戰案例解析(第2版)</title>
<author>陳小兵</author>
<publisher>電子工業出版社</publisher>
<price>84.90</price>
<year>2015-09-1</year>
</book>
</books>
xslt檔案和客戶端轉換對應的xslt檔案是一樣的,轉換的結果也是一樣的。
基本語法應用示例:變數,迴圈,條件,模板(方法),引數等
先看對應的轉換的xslt檔案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fun_c="urn:format" exclude-result-prefixes="fun_c">
<xsl:template match="/">
<!--變數-->
<xsl:variable name="paraPath" select="/books/book" ></xsl:variable>
<html>
<head>
<script type="text/javascript" language="javascript" >
var firstName = "<xsl:value-of select="$paraPath[@id='1']/title"/>";
alert(firstName);
</script>
</head>
<body>
<h2>Books List</h2>
<table border="1">
<tr bgcolor="#87CEFA">
<th align="left">Title</th>
<th align="left">author</th>
<th align="left">publisher</th>
<th align="left">price</th>
<th align="left">year</th>
</tr>
<!--模板(方法呼叫)-->
<xsl:call-template name="Each.Output">
<!--傳參-->
<xsl:with-param name="paraPath" select="$paraPath"/>
</xsl:call-template>
</table>
</body>
</html>
</xsl:template>
<!--模板(方法定義)-->
<xsl:template name="Each.Output">
<xsl:param name="paraPath"></xsl:param>
<!--迴圈-->
<xsl:for-each select="$paraPath">
<!--根據屬性id進行排序-->
<xsl:sort select="@id" data-type="number"/>
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="author"/>
</td>
<td>
<!--c#擴充套件方法SetRed(string value)呼叫-->
<xsl:value-of disable-output-escaping="yes" select="fun_c:SetRed(publisher)"/>
</td>
<td>
<!--內建方法,字串合併-->
<xsl:value-of select="concat(price,'元')"/>
</td>
<td>
<xsl:value-of select="year"/>
<!--條件判斷,如果值不為空為並且2015-->
<xsl:if test="year!=''and year ='2015' ">
<xsl:value-of select="'年'"/>
</xsl:if>
</td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
其中,<xsl:value-of disable-output-escaping="yes" select="fun_c:SetRed(publisher)"/>這個擴充套件方法需要搭配後臺語言定義,如果使用客戶端瀏覽器轉換,需要註釋掉。
XSLT 含有超過 100 個內建的函式,XQuery 1.0、XPath 2.0 以及 XSLT 2.0 共享相同的函式庫。
這些函式用於字串值、數值、日期和時間比較、節點和 QName 操作、序列操作、邏輯值,等等。關於 XSLT 的內建函式請引數:XSLT
函式參考手冊 和 XPath、XQuery
以及 XSLT 函式。
有時候內建的方法無法滿足要求,那麼就需要擴充套件方法了,例如上述的fun_c:SetRed(string value)方法。
首先xslt檔案的頭部xmlns:fun_c="urn:format" 定義了一個字首 fun_c而已,也就是名稱空間,沒有什麼特別的意義,但必須與其他用到這個字首的地方保持一致。如果不定義這麼一個名稱空間的話,直接不帶字首的呼叫 SetRed() 函式時,預設為的名稱空間是 fn,而 fn 中是不存這個函式的。
擴充套件函式必須為 public 的:
/// <summary>
///xslt的擴充套件
/// </summary>
public class XsltExt
{
/// <summary>
/// 擴充套件方法
/// 宣告必須為public
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public string SetRed(string str)
{
return string.Format("<span style='color:red'>{0}</span>", str);
}
}
直接上轉換相關程式碼:
/// <summary>
/// 載入xslt檔案
/// </summary>
private void LoadView(string xsltPath)
{
strXsltPath = xsltPath;
if (Cache && views.Keys.Contains(strXsltPath))
{
xct = views[strXsltPath];
}
else
{
xct = new XslCompiledTransform(Debug);
var xs = new XsltSettings { EnableScript = true, EnableDocumentFunction = true };
var settings = new XmlReaderSettings { ProhibitDtd = false };
// Create the reader.
var reader = XmlReader.Create(strXsltPath, settings);
try
{
xct.Load(reader, xs, new XmlUrlResolver());
if (Cache) views.Add(strXsltPath, xct);
}
finally
{
reader.Close();
}
}
}
/// <summary>
/// 通過xslt檔案轉換XML
/// </summary>
/// <param name="strXmlPath">XML檔案路徑</param>
/// <returns></returns>
public string TransferXmlByXslt(string xsltPath, string strXmlPath)
{
LoadView(xsltPath);
string pName = "urn:format";
string className = "WebApplicationXsltDemo.XsltExt,WebApplicationDemo";
Type t = Type.GetType(className);
if (className.Contains(','))
{
className = className.Split(',')[0];
}
object objEx = t.Assembly.CreateInstance(className);
XsltArgumentList xal = new XsltArgumentList();
xal.AddExtensionObject(pName, objEx);
var fs = new MemoryStream();
var outputstring = string.Empty;
try
{
////判斷檔案是否存在
if (File.Exists(strXmlPath) && File.Exists(strXsltPath))
{
////載入xml檔案
var doc = new XPathDocument(strXmlPath);
XPathNavigator nav = doc.CreateNavigator();
////轉換xml
xct.Transform(nav, xal, fs);
fs.Seek(0, SeekOrigin.Begin);
var stream = new StreamReader(fs);
outputstring = stream.ReadToEnd();
xct.TemporaryFiles.Delete();
}
else
{
return string.Empty;
}
}
catch (Exception ex)
{
}
finally
{
fs.Close();
fs.Dispose();
}
return outputstring;
} }
呼叫方法:
private ActionResult XsltTranslate()
{
string xslt = "XSLT_server.xslt";
string xml = "XMLFile.xml";
string serverpath = Server.MapPath("~");
XsltTransfer objXsltTransfer = new XsltTransfer();
<span style="font-family: Arial, Helvetica, sans-serif;">string result </span><span style="font-family: Arial, Helvetica, sans-serif;">= objXsltTransfer.TransferXmlByXslt(serverpath + xslt, serverpath + xml);</span>
Response.Write(result);
Response.End();
return new EmptyResult();
}
繼承(匯入)和過載(重定義)的應用 如果xslt檔案較多,而且可以複用,那麼,模板的匯入和重定義將派上用場。 例如,可以建立一個全域性的global.xslt檔案和通用方法comm.xslt檔案,裡面可以儲存各種全域性的變數和通用方法,再建立一個master.xslt檔案(匯入global.xslt和comm.xslt)做為基礎模板,其他的頁面只需要匯入master.xslt模板頁即可。 XSLT_Comm.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--定義方法,匯入後可以重寫該方法-->
<xsl:template name="Each.Output">
<xsl:param name="paraPath"></xsl:param>
</xsl:template>
</xsl:stylesheet>
XSLT_Global.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 全域性變數定義,也可以重寫此變數 -->
<xsl:variable name="paraPath" select="/books/book" ></xsl:variable>
</xsl:stylesheet>
在master.xslt中匯入前面兩個檔案:
<xsl:import href="XSLT_Global.xslt"/>
<xsl:import href="XSLT_Comm.xslt"/>
xslt+xml+asp.net mvc簡單的應用示例,如上有什麼更好建議或想法,也請大家多多指點。