代码改变世界

xslt函数扩展之使用自定义函数(C#,VB,JavaScript)

2012-07-12 14:44  AceYue  阅读(2283)  评论(0编辑  收藏  举报

          xslt作为扩展标记语言,其自身系统函数有限,远远满足不了我们的需求,要用xslt处理xml,必须要对数据做些处理(如果可以,我还是不会选择xslt)。

       今天就用xslt来处理文本中html标记为例,来讲讲如何利用xslt来执行自定义函数。

       我们来看看利用这个xml文本生成报表:

View Code
<Report ReportID="73" ReportName="Nielsen Customized GulfTalent Report" StartTime="Jun  1 2012 12:00AM" EndTime="Jun 30 2012 12:00AM" UserName="Aceyue" Department="All Departments" ReportDate="12 Jul 2012" JobPostingDate="06/01/2012 - 06/30/2012" JobStatus="1" Downloadtype="excel" Demain="http://dev.files.dimension.jobsdb.com" AC="Aceyue">
  <JobInformation>
    <Job AccountID="12100387" EntityCode="Aceyue" JobID="9" LangID="9" JobTitle="test29408" JobDes="&lt;FONT size=2&gt;ssssssssssssssssss&lt;/FONT&gt;" JobReference="ssssssss" JobLevelID="101" JobLevelDesc="ace" />
    <Job AccountID="12100387" EntityCode="Aceyue" JobID="10" LangID="10" JobTitle="sssssssssssss" JobDes="&lt;FONT size=2&gt;ssssssssssssssssssssssssssssssssssssssssssssssss&lt;/FONT&gt;" JobReference="sssssssss" JobLevelID="102" JobLevelDesc="ace_e" />
    <Job AccountID="12100387" EntityCode="ace" JobID="11" LangID="11" JobTitle="sssssssssssss" JobDes="&lt;FONT size=2&gt;ssssssssssssss&lt;/FONT&gt;" JobReference="" JobLevelID="103" JobLevelDesc="item" />
    <Job AccountID="12100387" EntityCode="ace" JobID="12" LangID="12" JobTitle="ssssssssss" JobDes="&lt;FONT size=2&gt;ssssssssss&lt;/FONT&gt;" JobReference="ssss" JobLevelID="101" JobLevelDesc="ace" />
    <Job AccountID="12100387" EntityCode="ace" JobID="13" LangID="13" JobTitle="bbbbbbbbb" JobDes="ssssssssssssssssssss" JobReference="" JobLevelID="102" JobLevelDesc="ace_e" />
    <Job AccountID="12100387" EntityCode="ace" JobID="14" LangID="14" JobTitle="ssssssssss" JobDes="&lt;FONT size=2&gt;ssssssssssssssssss&lt;/FONT&gt;" JobReference="" JobLevelID="102" JobLevelDesc="ace_e" />
  </JobInformation>
</Report>

         现在客户要求在生成的报表中没有html标记,即是不能用disable-output-escaping="yes"来直接执行html标记,或许要说可以用xslt系统函数translate()来做字符匹配,但是我们要匹配的标记何其之多,而且很多标记未知,对于translate()来说又不支持正则,所以我觉得用xslt来写自定义函数来执行replace将html替换为空。

         要使用xslt自定义函数,我们必须要引用函数命名空间:

View Code
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:user="urn:schemas-microsoft-com:xslt" >

         下面要定义自定义函数就可以用我们指定的工具前缀来定义(必须指明implements-prefix=我们自定义的前缀名)

View Code
  <msxsl:script language="javascript/C#/VB" implements-prefix="user">
    <![CDATA[
    //javascript function
    // C# Function
    // VB Function
    ]]>
  </msxsl:script>

         有了这些基础知识我们就可以来写我们自定义的函数来去掉文本中的html标记了,先来看看我们的C#函数:

View Code
  <msxsl:script language="C#" implements-prefix="user">
    <![CDATA[

    // C# Function
       public static string NoHTML(string Htmlstring)
      {
      Htmlstring = Regex.Replace(Htmlstring, @"<[^\\>]*>", "", RegexOptions.IgnoreCase);
      return Htmlstring;
      }
    ]]>
  </msxsl:script>

         VB函数:

View Code
  <msxsl:script language="VB" implements-prefix="user">
    <![CDATA[
    Function ReplaceBreakLineInExcelChar(str)

     Dim pattern As String = "<[\s\S]*?>"
     Dim regex As New Regex(pattern)
      str = regex.Replace(str, "")
    ReplaceBreakLineInExcelChar=str
    End Function


    ]]>
  </msxsl:script>

        javascript函数:

View Code
  <msxsl:script language="javascript" implements-prefix="user">
    <![CDATA[
    function replaceHTML(str)
    {
      
       return str.replace(/<[^>].*?>/g,'');

    }
    ]]>
  </msxsl:script>

        函数现在写好了,我们来看看这三种函数分别是怎么调用的:

View Code
<!--调用规则:“自定义前缀名:函数名 (值)”-->
<xsl:value-of select="user:ReplaceBreakLineInExcelChar(string(@JobDes))"/>
<xsl:value-of select="scripts:replaceHTML(string($pos))"/>
<xsl:value-of select="user:NoHTML(@JObDes)" />

       最后要注意的是在调用vb和javascript函数的时候,一定要注意参数类型转换,如果不转换默认传递的是 XPathArrayIterator 对象。所以我们在传递前用string()函数处理下。