2010-05-06 73 views
3

是否有可能爲XSLT中的for-each循環創建一個節點集,而不是爲我自己的元素集合?例如,我分割了一些字符串,並得到了一個字符串集合。我需要爲集合中的每個項目創建一個節點。我知道這個問題可以用遞歸模板解決,但我想知道是否有可能避免遞歸。XSLT for元素集合的每個循環

+0

很好的問題(1)。看到我的答案有兩種解決方案 - 他們都不需要使用擴展功能。 :) – 2010-05-06 13:28:41

回答

1

有兩個明顯的,直接的解決方案,其中之一僅在XSLT 2.0被支撐:

I.的一般解

這工作都與XSLT 1.0和XSLT 2.0。

定義你自己的命名空間,把你的節點設置爲這個命名空間中,哪些因素在全球放置在樣式表元素的兒童

下面是一個例子(<xsl:stylesheet>指令的孩子。):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" exclude-result-prefixes="my" 
> 
<xsl:output method="text"/> 

<my:nodes> 
    <string>Hello </string> 
    <string>World</string> 
</my:nodes> 

<xsl:variable name="vLookup" 
    select="document('')/*/my:nodes/*"/> 

<xsl:param name="pSearchWord" select="'World'"/> 

<xsl:template match="/"> 
    <xsl:if test="$pSearchWord = $vLookup"> 
    <xsl:value-of select= 
     "concat('Found the word ', $pSearchWord)"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉化是在任何XML文檔(未使用)施加,則結果爲

Found the word World 

請注意,我們根本不需要xxx:node-set()擴展功能。

二, XSLT 2.0/XPath 2.0解決方案

在XSLT 2.0/XPath 2.0中,可以始終使用序列類型。例如,人們可以簡單地定義一個變量包含在這樣的字符串的序列:

<xsl:variable name="vLookup" as="xs:string*" 
    select="'Hello', 'World'"/> 

並使用它作爲在下面的變換:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
<xsl:output method="text"/> 

<xsl:variable name="vLookup" as="xs:string*" 
    select="'Hello', 'World'"/> 

<xsl:param name="pSearchWord" select="'World'"/> 

<xsl:template match="/"> 
    <xsl:if test="$pSearchWord = $vLookup"> 
    <xsl:value-of select= 
     "concat('Found the word ', $pSearchWord)"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 
1

使用XPath擴展功能node-set()可以做到這一點。此功能受支持,例如由msxslexslt擴展。

MSDN給出瞭如何使用xsl:for-each使用msxsl:node-set()函數的一個例子:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       xmlns:user="http://www.contoso.com" 
       version="1.0"> 
    <xsl:variable name="books"> 
     <book author="Michael Howard">Writing Secure Code</book> 
     <book author="Michael Kay">XSLT Reference</book> 
    </xsl:variable> 

    <xsl:template match="/"> 
     <authors> 
      <xsl:for-each select="msxsl:node-set($books)/book"> 
       <author><xsl:value-of select="@author"/)</author> 
      </xsl:for-each> 
     </authors> 
    </xsl:template> 
</xsl:stylesheet> 
+0

看到我的答案兩種解決方案 - 他們都不需要使用擴展功能。 :) – 2010-05-06 13:29:00

0

你使用哪種平臺,你到底使用哪個XSLT處理器?您將需要以您的XSLT處理器支持的數據類型的形式提供字符串集合。哪一個完全取決於您的XSLT處理器支持的API。例如,使用.NET的XslCompiledTransform,您需要提供一個XPathNodeIteratator。