C# XSLT

使用XPath,我们可以很方便的搜索XML文档中的任何部分,因此具有很好的数据检索分析功能,近期业界兴起的半结构化文档技术大多就是以XPath为基础的。

  由于XPath技术是相当强的,而且是国际标准,跨平台的,因此大家有时间好好学习使用它。对于XPath的详细语法可访问网站 http://www.w3.org/TR/xpath ,若大家安装了MSDN2003版,也可参考 MSDN Library/XML Web Services/XML核心/SDK 文档/MSXML4.0 SDK/XPath Reference。这些电子文档全是英文,大家也可以购买一些专门讲述XML技术的中文书籍看看。

0_1285417177uSPT.gif

XSLT介绍

    XSLT是一种将XML文档转换为其他文本文档的语言,是建立在XML和XPath之上的国际标准,内容比较多,功能强大。

    对于编程人员来说,XSLT可以看作以前序遍历的方式专门处理XML树状结构的标记语言。以前编程根据XML文档输出纯文本数据时需要写代码以前序遍历方式的方式遍历XML文档对象组成的树状结构,对于每一个特定名称或特定层次的XML节点而输出不同的内容,这个过程比较复杂,代码量大,需用进行很多的状态判断。而XSLT则使用一种简洁明了的标记语言实现了相同的逻辑。因此XSLT从程序逻辑的角度看类似支持递归的编程语言,而且是专门处理XML文档的。

    XSLT转换过程会涉及到三个文本文档,一个是要处理的原始XML文档,第二个就是XSLT样式表文档,该文档包含了XSLT代码,XSLT代码本身就是XML格式,但使用了XML的名称空间。第三个就是XSLT处理输出的文本文档,注意,此处输出的是纯文本文档,这个文档具体是什么格式完全靠XSLT代码来决定,可以是另外一个XML文档,HTML文档,SQL语句字符串或者其他任意格式的字符串数据等等,XSLT转换只能输出纯文本文档,此外就没有限制输出文档的具体格式。

0_1285417226dsES.gif

XSLT范例

    下面使用一个XSLT范例来说明XSLT处理过程。

    在这个示意图中有三个图片,第一个是原始的包含数据的XML文档,第二个是XSLT样式表文档的内容,第三个就是转换结果。XSLT代码如下

  1. <xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   
  2.     <xsl:output method='xml' />   
  3.     <xsl:template match='/'>   
  4.         <html>   
  5.             <body>   
  6.                 <table border='1'>   
  7.                     <xsl:for-each select="Table/Record">   
  8.                         <tr>   
  9.                             <xsl:for-each select="*">   
  10.                                 <td>   
  11.                                     <xsl:value-of select="." />   
  12.                                 </td>   
  13.                             </xsl:for-each>   
  14.                         </tr>   
  15.                     </xsl:for-each>   
  16.                 </table>   
  17.             </body>   
  18.         </html>   
  19.     </xsl:template>   
  20. </xsl:stylesheet>  
<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method='xml' /> <xsl:template match='/'> <html> <body> <table border='1'> <xsl:for-each select="Table/Record"> <tr> <xsl:for-each select="*"> <td> <xsl:value-of select="." /> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

    数据XML文档是一个很简单的XML文档,此处不加说明了。重点说说XSLT样式表文档,可以看到XSLT样式表文档本身一个XML文档。它采用XML的树状结构来描述递归处理过程,也比较好理解。

    在样式表文档中,根元素为 xsl:stylesheet ,里面定义了一个名为xsl的名称空间,这个根节点及其属性值都是固定的。

xsl:output 元素是可选的,它的method属性用于指定输出文档的格式,可以设置为xml,html或text值。此处使用xml输出样式,说明输出的文档是XML格式的,XSLT转换会尽量生成XML文档,但不作保证,因此仍然有可能生成不合格的XML文档。

    xsl:template 用于定义一个XSLT模板,模板类似编程语言中的函数,可实现XSLT代码的重用。模板可以使用name属性定义名称,也可以使用match属性定义匹配的XPath路径,这个模板使用了match属性来匹配XML文档本身。

    然后是 html 元素,由于html元素没有使用xsl的前缀,因此不属于xslt代码,因此将原样输出,跟着后面的body,table元素也是一样的。

    xsl:for-each 元素类似C#中的foreach 语法结果,表示循环遍历元素,它使用select属性指定一个XPath相对路径,XSLT使用这个相对路径查询所有要遍历的XML节点,此时当前节点就是XML文档本身,因此XSLT处理器会调用XmlDocument的SelectNodes 函数来获得要遍历的XML节点,函数的参数就是Table/Record。于是我们开始循环遍历所有的Record元素了。

    在循环遍历Record元素时,对每一个Record元素都要输出xsl:for-each的子节点,首先是 tr 元素,这不是XSLT元素,因此原样输出。这里还套嵌定义了另外一个for-each元素,于是我们又开始了一个新的循环遍历了,新的循环指定的相对XPath路径是一个星号,表示匹配所有名称的子元素,这类似DOS命令Dir中使用星号匹配所有文件。此处表示循环遍历Record元素下面所有的字段元素。

    对每一个字段元素,首先输出td 元素,然后处理xsl:value-of 元素,xsl:value-of 表示输出指定相对路径的节点的值,这里指定的XPath是一个点号,表示当前节点本身,由于当前节点是XML元素,因此也就输出元素的文本内容,相当于输出XmlElement的InnerText 属性值。

0_1285417313ipUI.gif

为了让大家更清楚的了解XSLT执行过程,我写了一段C#代码来模拟实现这个XSLT转换过程,代码在演示程序的 codexslt.aspx 中。代码如下

  1. // 此处代码动态构造 xml 文档对象结构来输出XML文档   
  2. System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();   
  3. -------------- 查询数据库,填充XmlDoc --------------------------   
  4. // 保存输出结果的缓冲区   
  5. System.IO.StringWriter myResult = new System.IO.StringWriter();   
  6. myResult.WriteLine("<html>");   
  7. myResult.WriteLine("    <body>");   
  8. myResult.WriteLine("        <table border='1'>");   
  9. // 模拟 <xsl:for-each select="Table/Record">   
  10. foreach( System.Xml.XmlNode node in XmlDoc.SelectNodes("Table/Record"))   
  11. {   
  12.     myResult.WriteLine("        <tr>");   
  13.     // 模拟 <xsl:for-each select="*">   
  14.     foreach( System.Xml.XmlNode node2 in node.SelectNodes("*"))   
  15.     {   
  16.         myResult.Write("            <td>");   
  17.         // 模拟 <xsl:value-of select="." />   
  18.         myResult.Write( node2.InnerText );   
  19.         myResult.WriteLine("</td>");   
  20.     }   
  21.     myResult.WriteLine("        </tr>");   
  22. }   
  23. myResult.WriteLine("        </table>");   
  24. myResult.WriteLine("    </body>");   
  25. myResult.WriteLine("</html>");   
  26. myResult.Close();  
// 此处代码动态构造 xml 文档对象结构来输出XML文档 System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument(); -------------- 查询数据库,填充XmlDoc -------------------------- // 保存输出结果的缓冲区 System.IO.StringWriter myResult = new System.IO.StringWriter(); myResult.WriteLine("<html>"); myResult.WriteLine(" <body>"); myResult.WriteLine(" <table border='1'>"); // 模拟 <xsl:for-each select="Table/Record"> foreach( System.Xml.XmlNode node in XmlDoc.SelectNodes("Table/Record")) { myResult.WriteLine(" <tr>"); // 模拟 <xsl:for-each select="*"> foreach( System.Xml.XmlNode node2 in node.SelectNodes("*")) { myResult.Write(" <td>"); // 模拟 <xsl:value-of select="." /> myResult.Write( node2.InnerText ); myResult.WriteLine("</td>"); } myResult.WriteLine(" </tr>"); } myResult.WriteLine(" </table>"); myResult.WriteLine(" </body>"); myResult.WriteLine("</html>"); myResult.Close();

    代码很简单,这里我就不详细说明了。

    这里只是展示了一个非常简单的XSLT转换过程,XSLT和XPath语法不少,但花点时间是可以记下来的,编写XSLT模板是很有技巧性的。一般的我们要设计XSLT模板,首先获得要转换的XML文档样本以及所需转换结果的样本,这两个样本可能相差非常大,所有的差别都需要依靠XSLT转换模板来弥补,此时XSLT模板的编写不只是XSLT元素和函数的堆砌,而是需要同时兼顾输入和输出,还需要使用面向过程的编程思想。有时还需要编程对XSLT转换器进行扩展。

XML/XSLT在WEB开发中的应用

    XML/XSLT技术在WEB开发中可以发挥很大的应用,可以为WEB开发提供一种新的HTML页面生成方式。

    一般的在WEB开发中使用XML/XSLT技术主要有两种模式,一个是在服务器端执行XSLT转换,另一个是在客户端执行XSLT转换。

    在服务器端执行XSLT转换时,应用系统的业务模块生成包含要显示的数据的XML文档,然后调用事先写好的XSLT模板文档,执行XSLT转换,转换结果一般是HTML文档,当然也可以是其他类型的文本文档,此时客户端就可以将生成的HTML文档直接作为页面响发送到客户端浏览器中。客户端浏览器接受HTML文档并显示出来。在这个过程中,服务器端生成的XML文档,XSLT转换生成的HTML文档都是临时生成的文档,都可以存留在内存中,用完即可清除掉,不需要写到磁盘文件中。

    在客户端执行XSLT转换时,应用系统的业务模块生成包含要显示的数据的XML文档,加上XSLT转换信息标记,直接发送到客户端浏览器,客户端浏览器获得这个XML文档,根据其中的XSLT转换信息标记,从服务器上下载指定名称的XSLT文档。然后调用自己的XSLT转换器进行转换,在内存中生成了HTML文档并显示出来。此时显示的HTML页面不会出现在浏览器的缓冲文件夹中,也看不到HTML源代码,只能看到XML的源代码。

    由于XSLT转换是国际标准,在服务器端的转换结果和在客户端的转换结果是一样的。因此两种模式下浏览器中显示的页面内容是一样的。

0_1285417393jk54.gif

在传统的WEB开发中,我们都是直接使用业务系统拼凑出HTML字符串来生成要显示的HTML页面。虽然在ASP.NET中大量使用Web控件来简化开发,但web控件内部还是拼凑HTML字符串的。使用程序代码来拼凑HTML字符串会影响程序代码的可读性,很容易使得程序代码杂乱无章,而且生成的HTML可读性差。

    若使用XML/XSLT技术则可以有效的改善这种情况,由于XML文档格式检查非常严格,因此这就使得程序代码生成XML文档过程准确,不得出现错误,在这个环境下迫使程序员注意保持程序代码质量。而且生成的XML文档不只用于生成HTML页面,还能方便的向其他程序模块提供数据,并可充当WebService。

    考察WEB应用中生成的HTML代码,可以发现,大量的HTML页面中用于实现页面各种动态效果和页面格式的HTML代码多于直接显示数据的HTML代码,而且HTML代码普遍重复。这使得HTML页面代码臃肿,文件大,这会使得客户端浏览器下载页面缓慢。当采用XML/XSLT技术并在客户端执行XSLT转换时,由于服务器端发送的XML文档非常简洁,只包含纯粹的数据,并没有其他冗余的代码,因此文档小,下载快。与之配套的XSLT模板也是经过分析处理的,代码重复少,因此XSLT文件也小,这样客户端浏览器以前要下载一个很大的HTML文档,而现在只要下载两个较小的文档,这缩短了浏览器下载数据的时间。

    除了改善数据传输过程,浏览器自己执行XSLT转换,这样能将一部分的工作量从服务器端转移到客户端,此时服务器端只要快速生成包含数据的XML文档即完成工作。由于XSLT是广泛采用的国际标准,此时WEB系统能可靠的使用客户端的运算能力,从而减少服务器端运算压力,而利用客户端长期闲置的运算能力。

    虽然XML/XSLT技术具有很大的优势,但在实际开发中仍然存在不小的问题,其中最大的问题就是编制XSLT模板文件成本高。我们在开发WEB系统中使用了很多开发工具,包括VS.NET的WEB窗体设计器,美工人员使用的FrontPage,Dreamwave等等,都是用于生成HTML文档的,而HTML文档要求不严格,很多内容还不符合XML规范,因此需要使用各种方法将这些HTML文档转换为标准的XML文档,然后还需要分析页面结构,将这些XML文档加工成XSLT文档。在目前的技术条件下,这个过程成本比较大,使得XML/XSLT技术难于推广和普及。在此建议大家多多思考,如何低成本的将HTML文档转换为XSLT文档。

    而且XML/XSLT技术调试比较困难,对开发者要求很高,这也加大了这个技术的应用成本。而且目前的web系统中大量使用的WEB控件没有考虑到XML/XSLT技术,这也阻碍了这种新技术的应用。

使用C#执行XSLT转换

    在演示程序中,其中有些代码就是使用C#来执行XSLT转换的。

record.aspx

    演示程序中record.aspx演示了在服务器端执行XSLT转换,打开这个页面的C#代码中,在Page_Load函数中,首先是查询数据库并生成一个包含数据的XML文档。然后我们使用了一个名为xsl的页面参数,这个参数就指定了使用XSLT模板文件。若用户指定了该参数,我们开始执行XSLT转换。

    首先是创建一个XslTransform对象,调用它的Load函数来加载用户指定的XSLT模板文件,然后调用它的Transform函数,这个函数有四个参数,第一个就是包含数据的XML文档对象,第二个是XSLT转换参数的列表,此处未用,第三个就使输出转换结果的流对象,我们就使用页面输出流,最后一个是XML文档解析对象,此处未用。

  1. string strXSLRef = this.Request.QueryString["xsl"] ;   
  2. if( strXSLRef != null && strXSLRef.Length > 0 )   
  3. {   
  4.     // 根据页面参数指定的XSLT样式表名称执行XSLT转换   
  5.     strXSLRef = this.Server.MapPath( strXSLRef );   
  6.     System.Xml.Xsl.XslTransform transform = new System.Xml.Xsl.XslTransform();   
  7.     transform.Load( strXSLRef );   
  8.     transform.Transform( XmlDoc , null , this.Response.Output , null );   
  9. }  
string strXSLRef = this.Request.QueryString["xsl"] ; if( strXSLRef != null && strXSLRef.Length > 0 ) { // 根据页面参数指定的XSLT样式表名称执行XSLT转换 strXSLRef = this.Server.MapPath( strXSLRef ); System.Xml.Xsl.XslTransform transform = new System.Xml.Xsl.XslTransform(); transform.Load( strXSLRef ); transform.Transform( XmlDoc , null , this.Response.Output , null ); }

   可以看到在C#中执行XSLT转换是非常简单的,只要创建一个XslTransform对象,使用Load函数加载XSLT模板,使用Transform函数来执行XSLT转换即可。recordxml.aspx

    演示程序中的recordxml.aspx演示了在客户端执行XSLT转换,打开这个页面的C#代码,在Page_Load函数中,可以看到是查询数据库并使用XmlTextWriter输出包含数据的XML文档。其中有这么一段代码,首先判断一个名为xsl的页面参数是否存在,若存在则调用xmlwriter的WriteProcessingInstruction方法输出一段名为 xml-stylesheet的XML指令,这个指令的 href 属性值就使页面参数指定的XSLT模板文件名。

  1. // 输出XSLT样式表信息头   
  2. string strXSLRef = this.Request.QueryString["xsl"] ;   
  3. if( strXSLRef != null && strXSLRef.Length > 0 )   
  4. {   
  5.     xmlwriter.WriteProcessingInstruction(   
  6.         "xml-stylesheet" ,   
  7.         "type='text/xsl' href='" + strXSLRef + "'");   
  8. }  
// 输出XSLT样式表信息头 string strXSLRef = this.Request.QueryString["xsl"] ; if( strXSLRef != null && strXSLRef.Length > 0 ) { xmlwriter.WriteProcessingInstruction( "xml-stylesheet" , "type='text/xsl' href='" + strXSLRef + "'"); }

   客户端浏览器解析下载的XML文档,若遇到这个这段XML指令根据其中的href属性下载XSLT模板文件,然后执行XSLT转换,将生成的转化结果再作为HTML文档显示出来。

    在这个页面中,服务器端只负责输出数据XML文档,并提供XSLT模板文件下载,而XSLT转换就给客户端浏览器处理,这样就能减少服务器端的工作量并利用客户端的运算能力。

    注意这里的xml-stylesheet指令只对浏览器有效,一般其他的程序处理XML文档时会忽略掉这个XML指令。即使我们在服务器端使用XslTransform对象执行XSLT转换,这个XML指令也是毫无作用的,就像不存在一样。

使用C#执行XPath查询

    演示程序中的recordxpath.aspx就演示了使用C#执行XPath查询。打开这个页面的界面设计,可以看到其界面是比较简单地,其中一个单行文本框用于输入XPath字符串,一个大的多行文本框用于显示查询结果,还有一个按钮用于点击执行操作。页面代码主要在这个按钮的点击事件处理中。

    双击这个按钮,可以看到该按钮的点击事件处理代码。在该处理中,首先调用CreateRecordXMLDocument函数来获得包含数据的XML文档对象,生成XML文档的过程可以参考record.aspx的说明。

    程序生成包含数据的XML文档后,在从单行的文本输入框获得用户输入的XPath字符串,若用户输入的内容,则对XML文档的根节点调用SelectNodes方法,执行XPath查询,SelectNodes函数返回一个XmlNodeList列表,该列表中的元素类型是XmlNode。我们遍历这个列表,对其中每一个XML节点对象获得它的XML字符串,然后进行输出。

    若用户没有输入XPath字符串,则直接输出XML文档根节点的内容。

    在这里我们定义了GetXMLString 函数,这个函数主要是返回指定的XML节点对象的带缩进的XML字符串。用于取代Xml节点的OuterXml属性。

小结

    在本课程中,我们了解了XPath,XML/XSLT的基础知识。并演示使用C#使用XPath和XML/XSLT技术。

    XML及其派生的技术都是很重要的国际标准技术,对现代WEB开发具有很大的影响力,XML技术是一种优质的软件开发技术,因此大家要花点时间好好学习,熟练掌握XML及其派生技术将大大提高大家的软件开发能力。

转载于:https://www.cnblogs.com/kingdom_0/articles/2038978.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XSLT中,确实没有内置的split函数来分割字符串。但是你可以使用递归和substring函数来实现类似的功能。下面是一个示例代码,展示了如何在XSLT中实现一个简单的split函数: ``` <xsl:template name="split"> <xsl:param name="input" /> <xsl:param name="delimiter" select="','" /> <xsl:choose> <xsl:when test="contains($input, $delimiter)"> <xsl:value-of select="substring-before($input, $delimiter)" /> <xsl:text> </xsl:text> <xsl:call-template name="split"> <xsl:with-param name="input" select="substring-after($input, $delimiter)" /> <xsl:with-param name="delimiter" select="$delimiter" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$input" /> <xsl:text> </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> ``` 这个模板将接受两个参数:input和delimiter。它会逐个输出input中使用delimiter分隔的部分,并在每个部分后面添加一个换行符。 你可以在需要的地方调用这个模板,传递对应的参数来实现你的需求。比如,你可以在你的XSLT文档的某个模板中这样使用它: ``` <xsl:call-template name="split"> <xsl:with-param name="input" select="'ItemA,ItemB,ItemC'" /> <xsl:with-param name="delimiter" select="','" /> </xsl:call-template> ``` 这样,将会以换行符分隔的形式输出"ItemA"、"ItemB"和"ItemC"。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [在xslt中实现split方法对查询字符串进行分隔](https://blog.csdn.net/ddjq1044/article/details/101340306)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [利用xslt对xml中数据实现splite换行的总结](https://blog.csdn.net/gaotong2055/article/details/84128994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值