zoukankan      html  css  js  c++  java
  • XSLT

    XSLT 是一种用于将 XML 文档转换为 XHTML 文档或其他 XML 文档的语言;

    XPath 是一种用于在 XML 文档中进行导航的语言;

    本文目录

    1、XSLT的主要功能

    2、XSLT是如何工作的

    3、正确的样式表声明

    4、创建XSLT样式表

    5、template的使用

    6、valueof元素的使用

    7、foreach的使用

    8、sort的使用

    9、if的使用

    10、choosewhen的使用

    11、applytemplate的使用

    12、variable的使用

    13、param的使用

    14、script的使用

    XSLT的主要功能:

    1、它将一个没有形式表现的XML内容文档作为一个源树,将其转换为一个有样式信息的结果树;

    2、在XSLT文档中定义了与XML文档中各个逻辑成分相匹配的模板,以及匹配转换方式。这样可以将转换为另一个逻辑结构的XML文档、HTML文档、XHTML文档、VRML文档、SVG文档等等。 

    XSLT是如何进行工作的?

    XSLT 使用 XPath 来定义源文档中可匹配一个或多个预定义模板的部分。一旦匹配被找到,XSLT 就会把源文档的匹配部分转换为结果文档。

    转换模式:一般分服务器端和客户端转换两种;

    服务器端转换简单实例:

    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string xmlpath = Server.MapPath("books.xml");
            string xsltpath = Server.MapPath("XSLTFile2.xslt");
            XPathDocument xpd = new XPathDocument(xmlpath);
            XslCompiledTransform xslcom = new XslCompiledTransform();
            xslcom.Load(xsltpath);
            xslcom.Transform(xpd,null, Response.Output);
        }
    }
    客户端转换实例:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>无标题页</title>
         <script for="window" event="onload" type="text/javascript">
    
                divResults.innerHTML = mybook.transformNode(stylesheet);
    
        </script>
    </head>
    <body>
    
      <xml  src="books.xml" id="mybook"></xml>
        <xml src="XSLTFile2.xslt"  id="stylesheet"></xml>
          <div id="divResults"></div>
       
    </body>
    </html>

    正确的样式表声明

    把文档声明为 XSL 样式表的根元素是 <xsl:stylesheet> 或 <xsl:transform>。

    注释: <xsl:stylesheet> 和 <xsl:transform> 是完全同义的,均可被使用!

    根据 W3C 的 XSLT 标准,声明 XSL 样式表的正确方法是:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    或者:

    <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    如需访问 XSLT 的元素、属性以及特性,我们必须在文档顶端声明 XSLT 命名空间。

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 指向了官方的 W3C XSLT 命名空间。如果您使用此命名空间,就必须包含属性 version="1.0"。

    接下来从一个简单的XML文档开始(books.xml),

    <?xml version="1.0" encoding="utf-8" ?>
    <bookstore>
      <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
      </book>
      <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
      </book>
      <book category="WEB">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
      </book>
    </bookstore>
    

    创建XSLT样式表:  

    然后创建一个带有转换模板的 XSL 样式表(booksXSLT.xlst):
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
              </tr>
              <xsl:for-each  select ="//book">
                <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
              </tr>
                
              </xsl:for-each>
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    

    向文档books.xml中添加xslt样式表引用:

    <?xml version="1.0" encoding="utf-8" ?>
    <?xml-stylesheet type="text/xsl" href="bookstoreXSLT.xslt"?>
    <bookstore>
      <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
      </book>
      <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
      </book>
      <book category="WEB">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
      </book>
    </bookstore>
    

    如果您使用的浏览器兼容 XSLT,它会很顺利地把您的 XML 转换为 XHTML;XSL 样式表由一个或多套被称为模板(template)的规则组成。每个模板含有当某个指定的节点被匹配时所应用的规则。

    <xsl:template> 元素

    <xsl:template> 元素用于构建模板。match 属性用于关联 XML 元素和模板。match 属性也可用来为整个文档定义模板。match 属性的值是 XPath 表达式;

    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
              </tr>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    由于 XSL 样式表本身也是一个 XML 文档,因此它总是由 XML 声明起始:
    <?xml version="1.0" encoding="utf-8"?>

    下一个元素,<xsl:stylesheet>,定义此文档是一个 XSLT 样式表文档(连同版本号和 XSLT 命名空间属性)。<xsl:template> 元素定义了一个模板。match="/" 属性则把此模板与 XML 源文档的根相联系。<xsl:template> 元素内部的内容定义了写到输出结果的 HTML 代码。最后两行定义了模板的结尾,及样式表的结尾。

    上例的缺点是没能够把XML中的数据复制并输出,下面的事例使用使用 <xsl:value-of> 元素从 XML 元素选取值;

    <xsl:value-of> 元素

    <xsl:value-of> 元素用于提取某个选定节点的值,并把值添加到转换的输出流中:
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
              </tr>
              
                <tr>
                <td>
                  <xsl:value-of  select ="/bookstore/book//title"/>
                </td>
                <td>
                  <xsl:value-of  select ="/bookstore/book/author"/>
                </td>
              </tr>
                
          
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    select 属性的值是一个 XPath 表达式。此表达式的工作方式类似于定位某个文件系统,在其中正斜杠(/)可选择子目录,上例的缺点是仅有一条数据输出;下面的例子使用 <xsl:for-each> 元素来循环遍历 XML 元素,并显示所有的记录

    <xsl:for-each>元素

    <xsl:for-each> 元素可用于选取指定的节点集中的每个 XML 元素。
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
              </tr>
              <xsl:for-each  select ="/bookstore/book">
                <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
              </tr>
                </xsl:for-each>
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    select 属性的值是一个 XPath 表达式。此表达式的工作方式类似于定位某个文件系统,在其中正斜杠可选择子目录。

    <xsl:sort>元素

    对结果进行排序,在 XSL 文件中的 <xsl:for-each> 元素内部添加一个 <xsl:sort> 元素;
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
              </tr>
              <xsl:for-each  select ="/bookstore/book">
                <xsl:sort order ="descending"  select="title"/>
                <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
              </tr>
                </xsl:for-each>
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    select 属性指示需要排序的 XML 元素;

    <xsl:if> 元素

    <xsl:if> 元素用于放置针对 XML 文件内容的条件测试,如需添加有条件的测试,请在 XSL 文件中的 <xsl:for-each> 元素内部添加 <xsl:if> 元素:
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
                <td>Price</td>
              </tr>
              <xsl:for-each  select ="/bookstore/book">
                <xsl:if  test ="price>30">
                <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
                  <td>
                    <xsl:value-of select ="price"/>
                  </td>
              </tr>
                </xsl:if>
                </xsl:for-each>
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    必选的 test 属性的值包含了需要求值的表达式。

    <xsl:choose>元素

    <xsl:choose>结合<xsl:when>和<xsl:otherwise>来表达多重条件的测试:要插入针对 XML 文件的多重条件测试,请向 XSL 文件添加 <xsl:choose>、<xsl:when> 以及 <xsl:otherwise>:
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
                <td>Price</td>
              </tr>
              <xsl:for-each  select ="/bookstore/book">
             
                <tr>
                  
                <td>
                  <xsl:value-of  select ="title"/>
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
                  <xsl:choose  >
                    <xsl:when  test ="price=30">
                      <td bgcolor="red">
                    <xsl:value-of select ="price"/>
                     </td>
                    </xsl:when>
                    <xsl:when test ="price < 30">                  
                      <td bgcolor="silver">
                        <xsl:value-of select ="price"/>
                      </td>
                    </xsl:when>
                    <xsl:otherwise >
                      <td >
                        <xsl:value-of select ="price"/>
                      </td>
                    </xsl:otherwise>
                  </xsl:choose>
                  
              </tr>
               
                </xsl:for-each>
              
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>
    
    必选的 test 属性的值包含了需要求值的表达式;

     <xsl:apply-templates> 元素

    <xsl:apply-templates> 元素可把一个模板应用于当前的元素或者当前元素的子节点。假如我们向 <xsl:apply-templates> 元素添加一个 select 属性,此元素就会仅仅处理与属性值匹配的子元素。我们可以使用 select 属性来规定子节点被处理的顺序。请看下面的 XSL 样式表:

    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
                <td>Price</td>
              </tr>       
                 <xsl:apply-templates  ></xsl:apply-templates> <!--省略select属性表示选取当前节点的所有子节点-->            
            </table>
          </body>
        </html>
       
      </xsl:template>
      <xsl:template  match ="bookstore/book">
        <tr>
        <td>
          <xsl:apply-templates  select ="title"></xsl:apply-templates>
        </td>
        <td>
          <xsl:apply-templates  select ="author"/>
        </td>
        <td>
    
          <xsl:apply-templates  select ="price"></xsl:apply-templates>
        </td>
        </tr>
      </xsl:template>
      <xsl:template  match ="title">
        <xsl:value-of  select ="."/><!--.代表当前节点-->
      </xsl:template>
      <xsl:template  match ="author">
        <xsl:value-of  select ="."/>
      </xsl:template>
      <xsl:template  match ="price">
        <xsl:value-of  select ="."/>
      </xsl:template>
    </xsl:stylesheet>
    
     <xsl:apply-templates  >省略select属性表示选取当前节点的所有子节点;
    <xsl:value-of  select ="."/>:.代表当前节点。

    <xsl:variable>元素

    在参数或者变量声明以后,使用的时候,直接$参数名或变量名即可;参数值或者变量值可以直接赋值或者从XML文档获取;
      <xsl:param  name ="discount"  select ="0.50"></xsl:param>
     <xsl:variable name="price" select="user:price"></xsl:variable>
    <xsl:variable>事例:
    <?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:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
                <td>Price</td>
              </tr>
             
                <xsl:for-each  select ="bookstore/book">
                  <xsl:variable  name ="x" select ="price"/> 
                  <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
                <td>
                  <xsl:value-of  select ="$x"/>
                </td>
                  </tr>  
                </xsl:for-each>
                
            </table>
          </body>
        </html>
       
      </xsl:template>
     
    </xsl:stylesheet>
    
    变量x在每次循环的时候获取price的值,然后通过$x调用;

    <xsl:param>元素

    <xsl:param>元素使用实例:通过参数过滤数据
    <?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:param  name ="line" ></xsl:param>
      <xsl:template match ="/">
        <html>
          <head></head>
          <body>
            <h2>BookStore</h2>
            <table border="1">
              <tr>
                <td>Title</td>
                <td>Author</td>
                <td>Price</td>
              </tr>
             
                <xsl:for-each  select ="bookstore/book">
                  <xsl:if  test ="price > $line">
                 
                  <tr>
                <td>
                  <xsl:value-of  select ="title"/>
                
                </td>
                <td>
                  <xsl:value-of  select ="author"/>
                </td>
                <td>
                  <xsl:value-of  select ="price"/>
                </td>
                  </tr>  
                  </xsl:if>
                </xsl:for-each>
                
            </table>
          </body>
        </html>
       
      </xsl:template>
     
    </xsl:stylesheet>
    
    <xsl:param  name ="line" ></xsl:param>在文档中没有赋值,他的值来自于客户端;参数也是通过$参数名的方式调用;
    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
    
           
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            XmlDocument xd = new XmlDocument();
            XsltArgumentList args = new XsltArgumentList();
            args.AddParam("line","",text1.Text);
            xd.Load(Server.MapPath("bookstore.xml"));
            XslCompiledTransform  xslcom=new XslCompiledTransform ();
            xslcom.Load(Server.MapPath("bookstoreXSLT.xslt"));
            xslcom.Transform(xd,args, Response.Output);
        }
    }

    XSLT With SCript

    带有脚本的XSLt文档:

    <?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"
                     xmlns:user="dd"
    >
      <msxsl:script language ="C#"  implements-prefix ="user">
        <![CDATA[
          public string ReturnDiscount(string price)
          {
            decimal priceValue=Convert.ToDecimal(price);
            return (priceValue- priceValue * 15 / 100).ToString();
          }
        ]]>
      </msxsl:script>
       
    
        <xsl:template match="/">
          <html>
            <head></head>
            <body>
              <h2>BookStore</h2>
              <table border="1">
                <tr>
                  <td>Title</td>
                  <td>Author</td>
                  <td>Price</td>
                  <td>折后价</td>
                </tr>
    
                <xsl:for-each  select ="user:books/user:book">
                 
    
                    <tr>
                      <td>
                        <xsl:value-of  select ="user:title"/>
    
                      </td>
                      <td>
                        <xsl:value-of  select ="user:author"/>
                      </td>
                      <td>
                        <xsl:value-of  select ="user:price"/>
                      </td>
                      <td>
                        <xsl:value-of  select ="user:ReturnDiscount(user:price)"/>
                      </td>
                    </tr>
           
                </xsl:for-each>
    
              </table>
            </body>
          </html>
        </xsl:template>
    </xsl:stylesheet>
    

    implements-prefix 属性是必选项。 此属性用于声明命名空间并将其与脚本块关联;

     XmlDocument xd = new XmlDocument();
            XsltArgumentList args = new XsltArgumentList();
         
            xd.Load(Server.MapPath("books.xml"));
            XsltSettings xs = new XsltSettings(false, true);
            XslCompiledTransform  xslcom=new XslCompiledTransform ();
            xslcom.Load(Server.MapPath("bookscript.xslt"),xs,null);
            xslcom.Transform(xd,null, Response.Output);
    
    XsltSettings xs = new XsltSettings(false, true);设置xslt中EnableScript为true;

    小结:在变成过程中经常碰到的类:

     XsltArgumentList、 XPathDocument、XsltSettings、XslCompiledTransform

    常用方法:Load、Transform;

  • 相关阅读:
    HttpServletRequest字符集问题
    原码反码补码
    无符号1byte转int
    初识spark的MLP模型
    冗余系统必要性
    shiro的rememberMe不生效
    阅读笔记-异常
    优雅的处理异常
    使用Maven搭建SpringMVC
    Jmeter发送soap请求
  • 原文地址:https://www.cnblogs.com/LittleFeiHu/p/1893273.html
Copyright © 2011-2022 走看看