XSLT:在字符串数组上使用follow-sibling?

时间:2017-10-27 09:25:34

标签: xslt xpath xslt-1.0 xslt-2.0

标记了包含文件路径的属性(例如/ dir1 / dir2 / dir3),我现在有一个字符串数组(或节点集?)。

我想以递归的方式处理第一个项目并完成剩下的工作 - 并且希望使用' follow-sibling'来实现这一目标。轴。然而,事实证明它需要实际的元素而不仅仅是字符串。

<xsl:template match="s:universe">
    <xsl:call-template name="createSubFolder">
        <xsl:with-param name="folderNames" select="tokenize(@path, '/')" />
    </xsl:call-template>
</xsl:template>

<xsl:template name="createSubFolder">
    <xsl:param name="folderNames" />
    <xsl:if test="count($folderNames) > 0">
        <folder>
            <xsl:attribute name="name" select="$folderNames[1]" />
            <xsl:if test="position() &lt; count($folderNames)">
                <folder>
                    <xsl:call-template name="createSubFolder">
                        <xsl:with-param name="folderNames" select="$folderNames[1]/following-sibling::text()" />
                    </xsl:call-template>
                </folder>
            </xsl:if>
        </folder>
    </xsl:if>
</xsl:template>

我目前想象的唯一解决方案是创建一个自定义函数,将数组的尾端提供给模板 - 但我觉得可能/必须有更好的方法。

1 个答案:

答案 0 :(得分:1)

正如Martin Honnen在评论中提到的,tokenize(@path, '/')返回字符串的序列。因此,您不能将following-sibling轴用于字符串类型。

您可以使用subsequence($folderNames,2)$folderNames[position() gt 1]来使用递归调用,如下所示:

<xsl:template name="createSubFolder">
    <xsl:param name="folderNames" as="xs:string*"/>
    <xsl:if test="exists(($folderNames[1]))">
        <folder>
            <xsl:attribute name="name" select="$folderNames[1]" />
            <xsl:call-template name="createSubFolder">
                <xsl:with-param name="folderNames" select="subsequence($folderNames,2)"/>
            </xsl:call-template>
        </folder>
    </xsl:if>
</xsl:template>