我是XSL中的新手,但是我需要XSL文件将具有相同名称属性的节点合并到一个元素中 - 对于子节点也是如此 - 并且如果有节点'具有不同的名称,则将其放入其中, XML的一个例子如下。
<?xml version="1.0" encoding="UTF-8"?>
<test>
<component name="root">
<component name="c2">
<component name="c3">
<component name="c4" />
</component>
</component>
</component>
<component name="root">
<component name="c2">
<component name="A4" />
</component>
<component name="root">
<component name="A3" />
</component>
<component name="root">
<component name="X1">
<component name="X2" />
</component>
</component>
</component>
<component name="difRoot">
</component>
</test>
所需的输出如下
<output>
<component name="root">
<component name="c2">
<component name="c3">
<component name="c4"/>
</component>
<component name="A4"/>
</component>
<component name="A3"/>
<component name="X1">
<component name="X2"/>
</component>
</component>
<component name="difRoot"/>
</output>
由于
答案 0 :(得分:2)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kComponentByName" match="component" use="@name"/>
<xsl:template match="test">
<output>
<xsl:call-template name="merge">
<xsl:with-param name="pSequence" select="*"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="merge">
<xsl:param name="pSequence" select="/.."/>
<xsl:if test="$pSequence">
<xsl:variable name="vName" select="$pSequence[1]/@name"/>
<xsl:for-each select="$pSequence[1]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:call-template name="merge">
<xsl:with-param name="pSequence"
select="key('kComponentByName',$vName)
/component[@name != $vName]"/>
</xsl:call-template>
</xsl:copy>
</xsl:for-each>
<xsl:call-template name="merge">
<xsl:with-param name="pSequence"
select="$pSequence[@name != $vName]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<output>
<component name="root">
<component name="c2">
<component name="c3">
<component name="c4" />
</component>
<component name="A4" />
</component>
<component name="A3" />
<component name="X1">
<component name="X2" />
</component>
</component>
<component name="difRoot" />
</output>
注意:递归层次结构未完全解决,只会阻止自己成为孩子。
更新:命名模板说明:如果pSequence
不为空,请取出第一个节点,然后复制自身并将模板应用于所有component
元素的子元素相同的@name
(过滤那些@name
也是如此);最后称自己过滤pSequence
个component
元素与处理过的@name
相同{{1}}。因此,它逐级逐级地逐节点过滤兄弟姐妹和孩子。完全圆形预防应该通过一个带有祖先名称的序列进行过滤。这只是运动......