首页 > 解决方案 > 递归连接父属性

问题描述

给定以下 XML:

<package>
    <node name="a">
        <node name="b"/>
        <node name="c"/>
        <node name="d">
            <node name="e"/>
            <node name="f"/>
            <node name="g">
                <node name="h"/>
            </node>
        </node>    
    </node>
</package>

我基本上想在连接name每个父node元素的属性直到最后一个node元素的同时展平树:

<package>
    <node name="a-b"/>
    <node name="a-c"/>
    <node name="a-d-e"/>
    <node name="a-d-f"/>
    <node name="a-d-g-h"/>
</package>

到目前为止,我所做的是node使用模板正确生成所有元素的平面列表,并且xsl:copy-of

<xsl:template match="//node">
    <xsl:copy-of select="current()"/>
</xsl:template>

这给了我:

<package>
    <node name="b"/>
    <node name="c"/>
    <node name="e"/>
    <node name="f"/>
    <node name="h"/>
</package>

但我不确定如何从这里正确继续。我的意图是扩展模板并使用xsl:attributexsl:for-each连接和修改属性:

    <xsl:template match="node/@name">
        <xsl:attribute name="name">
            <xsl:for-each select="ancestor::node">
                <xsl:if test="position() > 1">.</xsl:if>
                <xsl:value-of select="@name"/>
            </xsl:for-each>
        </xsl:attribute>
    </xsl:template>

但是,这只会打印node的数据(如果有)。我在这里想念什么?

我有 XSLT 2.0 可用,我的灵感来自这个SO question

标签: xmlxsltxslt-2.0

解决方案


使用string-join

<xsl:template match="node">
  <node name="{string-join(ancestor-or-self::node/@name, '-')}"/>
</xsl:template>

推荐阅读