基于xslt的简单应用开发

来源:互联网 发布:three.js注释库 编辑:程序博客网 时间:2024/06/05 06:26

一.本文所涉及的内容

  1. 本文所涉及的内容
  2. xslt及其应用场景
  3. 简单应用示例
    1. 转换示例:通过xslt将xml转换成html
    2. 基本语法应用示例:变量,循环,条件,模板(方法),参数等
    3. 服务器端转换方式-结合c#进行方法扩展
    4. 继承(导入)和重载(重定义)的应用

二.xslt及其应用场景

XSLT可扩展样式表转换语言(Extensible Stylesheet Language Transformations)是一种对XML文档进行转化的语言,它的作用相当于就是样式表(css)之于HTML文件,XSLT中的T代表英语中的“转换”(transformation)。它是XSL(Extensible stylesheet language)规范的一部分。XSLT一个比较显著的特点是数据与显示分离,数据可以根据需要的样式或者形式进行展示,转换的方式可以为分为客户端转换(需要浏览器支持xslt)和服务器端转换。  

常用应用场景如下:

第一,将源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 ListTitleauthorpublisherpriceyearHTML5+CSS3从入门到精通(附1DVD)李东博清华大学出出版社42.902015安全之路——Web渗透技术及实战案例解析(第2版)陈小兵电子工业出版社84.902015-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 函数。


服务器端转换方式-结合c#进行方法扩展  
有时候内置的方法无法满足要求,那么就需要扩展方法了,例如上述的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简单的应用示例,如上有什么更好建议或想法,也请大家多多指点。


0 0
原创粉丝点击