标记了一个包含文件路径的属性(例如/dir1/dir2/dir3),我现在有一个字符串数组(或节点集?
我想递归处理第一项并传递其余项 - 并希望使用"后续兄弟"轴完成此操作。但是,事实证明,它期望实际元素而不仅仅是字符串。
<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>
我目前想象的唯一解决方案是创建一个自定义函数,该函数将数组的尾端馈送到模板中 - 但我感觉可能/必须有更好的方法。
正如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>