XSLT for-each循环用于元素集合

时间:2010-05-06 08:41:18

标签: xslt recursion loops foreach

是否可以在XSLT中为for-each循环而不是为节点集创建,而是为了我自己的元素集合?例如,我拆分了一些字符串,结果就是字符串集合。我需要为集合中的每个项目创建一个节点。我知道这个问题可以通过递归模板解决,但我想知道是否可以避免递归。

3 个答案:

答案 0 :(得分:1)

可以使用XPath扩展函数node-set()来实现。支持此功能,例如通过msxslexslt扩展程序。

MSDN举例说明如何将msxsl:node-set()函数与xsl:for-each一起使用:

<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>

答案 1 :(得分:1)

有两个明显,直接的解决方案,其中一个仅在XSLT 2.0中受支持:

予。一般解决方案

这适用于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()扩展功能。

II。 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>

答案 2 :(得分:0)

您使用哪个平台,您使用哪种XSLT处理器?您需要以XSLT处理器支持的数据类型的形式提供您的字符串集合。究竟是哪一个完全取决于您的XSLT处理器支持的API。 例如,使用.NET的XslCompiledTransform,您需要提供XPathNodeIteratator。