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

时间:2021-02-23 21:46:11

  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这两个函数逐步拆分分解出来的字符串,直到分解完毕。