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這兩個函數逐步拆分分解出來的字串,直到分解完畢。