基于xslt的简单应用开发

2 篇文章 0 订阅

一.本文所涉及的内容

  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 List
Titleauthorpublisherpriceyear
HTML5+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简单的应用示例,如上有什么更好建议或想法,也请大家多多指点。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值