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;

posted @ 2010-12-08 17:05  麻将我会  阅读(972)  评论(3编辑  收藏  举报