标记了包含文件路径的属性(例如/ 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() < 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>
我目前想象的唯一解决方案是创建一个自定义函数,将数组的尾端提供给模板 - 但我觉得可能/必须有更好的方法。
答案 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>