通过xslt合并具有相同名称的节点

时间:2010-05-04 13:53:32

标签: xslt

我尝试通过XSLT更改我的XML文件。 该文件类似于:

<A1>
<A2>
<A3>
<b>a</b>
<b>b</b>
...
</A3>
</A2>
</A1>
<A1>
<A2>
<A3>
<b>1</b>
<c>2</c>
</A3>
</A2>
</A1>
...

结果应为:

<A1>
<A2>
<A3>
<b>a, b</b>
</A3>
</A2>
</A1>
<A1>
<A2>
<A3>
<b>1</b>
<c>2</c>
</A3>
</A2>
</A1>

有人可以帮我吗?!!!! 此致

1 个答案:

答案 0 :(得分:0)

这在很大程度上取决于你未提及的一些事情,例如,子元素总是按顺序排列(即它总是<b><b><c>或者它可能是<b><c><b>)并且是元素始终是<A3>元素的子元素。

对于上面的XML,我编写了一个模板来处理元素,如下所示:

<xsl:template match="A3">
    <A3>
    <xsl:for-each select="*">
            <xsl:choose>
                    <xsl:when test="following-sibling::*[name()=current()/name()] and not(preceding-sibling::*[name()=current()/name()])">
                        <xsl:element name="{name()}">
                        <xsl:for-each select="self::* | following-sibling::*[name()=current()/name()]">
                                <xsl:value-of select="."/>
                                <xsl:if test="position() != last()">,</xsl:if>
                            </xsl:for-each>
                            </xsl:element>
                        </xsl:when>
                    <xsl:when test="not(following-sibling::*[name()=current()/name()]) and preceding-sibling::*[name()=current()/name()]">
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:copy-of select="."/>
                            </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
        </A3>
</xsl:template>

这可能是一种更简单的方法,但这至少是一种方式。它可能很慢,具体取决于您对特定节点的子元素数量。