在xslt中实现split方法对查询字符串进行分隔

  xslt本身并没有提供现成的split方法让我们对给定的查询字符串进行有效的分隔,不过我们可以借助于substring-before和substring-after函数来实现split的效果。先看一个应用需求:

要进行格式化的xml文档内容

<?xml version="1.0" encoding="utf-8"?>
<Items>
  
<ItemA>a</ItemA>
  
<ItemB>b</ItemB>
  
<ItemC>c</ItemC>
  
<ItemD>d</ItemD>
  
<ItemE>e</ItemE>
</Items>

用于查找节点内容的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:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  
<xsl:param name="tag"/>

  
<xsl:template match="/">
        
<xsl:value-of select="//*[name() = $tag]" disable-output-escaping="yes"/>
  
</xsl:template>
</xsl:stylesheet>

  将要查找的节点名称作为参数tag的值传递给上述xslt文档,它便能将xml文档中相关节点中的内容输出到页面上,如果xml文档节点中存储的是html标记内容,则在页面上显示的就是具有实际意义的超文本标记,这个是通过disable-output-escaping="yes"属性来决定的,如果该属性的值为false,则html标记会原样输出到页面上。

  现在的问题是,我想要上述xslt文档能通过接收到的参数输出多个匹配的xml节点中的内容,如接收到的参数为"ItemA,ItemB,ItemC",则在页面上依次输出这三个节点中的内容,怎么实现呢?最先想到的办法就是在xslt中实现一个类似于split函数的功能,对参数tag的值进行分解,最好是能将分解后的结果存放到数组中,然后遍历数组依次输出检索到的结果。但是xslt中没有split函数,而且也没有数组这种“高级”数据结构,xslt本身是xml文档,它只能实现一些比较简单的逻辑和运算。事实上,在xslt的XPath函数中有两个函数可以实现我们的需求。

  substring-before(string1, string2)函数:返回string2在string1中出现之前的子字符串,如substring-before("ItemA,ItemB,ItemC", ",")返回的结果是"ItemA"。

  substring-after(string1, string2)函数:返回string2在string1中出现之后的子字符串,如substring-after("ItemA,ItemB,ItemC", ",")返回的结果是"ItemB,ItemC"。

  有了这两个函数我们就可以实现上面所说的类似于split函数的功能了,下面是修改后的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:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  
<xsl:param name="tag"/>

  
<xsl:template match="/">

  
<xsl:call-template name="output-tokens">
      
<xsl:with-param name="list" select="$tag"/>
      
<xsl:with-param name="separator">,</xsl:with-param>
    
</xsl:call-template>
  
</xsl:template>

  
<xsl:template name="output-tokens">
    
<xsl:param name="list" />
    
<xsl:param name="separator" />
    
<xsl:variable name="newlist" select="concat(normalize-space($list), $separator)" />
    
<xsl:variable name="first" select="substring-before($newlist, $separator)" />
    
<xsl:variable name="remaining" select="substring-after($newlist, $separator)" />

    
<xsl:value-of select="//*[name() = $first]" disable-output-escaping="yes"/>
    
<br/>

    
<xsl:if test="substring-before($remaining, $separator) != ''">
      
<xsl:call-template name="output-tokens">
        
<xsl:with-param name="list" select="$remaining" />
        
<xsl:with-param name="separator" select="$separator" />
      
</xsl:call-template>
    
</xsl:if>
  
</xsl:template>

</xsl:stylesheet>
  方法output-tokens用来进行字符串的拆分并在循环中依次输出查询结果,基本思路就是不断地调用substring-before和substring-after这两个函数逐步拆分分解出来的字符串,直到分解完毕。  
posted @ 2009-11-16 12:51  Jaxu  阅读(5335)  评论(3编辑  收藏  举报