XSLT
XSLT 是一种用于将 XML 文档转换为 XHTML 文档或其他 XML 文档的语言;
XPath 是一种用于在 XML 文档中进行导航的语言;
本文目录
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样式表:
<?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>
<?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> 元素
<?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>
<xsl:for-each>元素
<?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>
<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>
<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>
<xsl:choose>元素
<?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>
<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>元素
<xsl:param name ="discount" select ="0.50"></xsl:param> <xsl:variable name="price" select="user:price"></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>
<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;