使用XSLT将子节点从XML文件移动到Parent

时间:2014-05-21 16:17:34

标签: xml xslt

我有一个XML文件,如下所示。 CONTROLHOLDER是一个家长,它可以将其中的儿童CONTROLHOLDER提升到第n级。 但是我想把所有这些孩子的CONTROLHOLDER及其内容拿出来并将其作为父母置于父母CONTROLHOLDER之下。 请告诉我这个

的最佳推荐方式
<CONTROLS>
<CONTROLHOLDER ID="CH1">
    <CONTROL11 ID="ED1">        
    <CONTROL11>
    <CONTROL12 ID="ED2">
    </CONTROL12>
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH2">
    <CONTROL21 ID="ED3">        
    <CONTROL21>
    <CONTROL22 ID="ED4">
    </CONTROL22>
        <CONTROLHOLDER  ID= "CH21">
            <CONTROL211 ID="ED5" >  
            <CONTROL211>
            <CONTROL212 ID="ED6" >
            </CONTROL212>
        </CONTROLHOLDER>
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH3">
    <CONTROL31 ID="ED31">   
    <CONTROL31>
    <CONTROL32 ID="ED32">
    </CONTROL32>
        <CONTROLHOLDER  ID= "CH31">
            <CONTROL311 ID= "ED311">
            <CONTROL311>
            <CONTROL312 ID= "ED312">
            </CONTROL312>
                <CONTROLHOLDER  ID= "CH313">
                    <CONTROL3131 ID= "ED3131">
                    <CONTROL3131>
                    <CONTROL3132 ID= "ED3132">
                    </CONTROL3132>
                </CONTROLHOLDER>
        </CONTROLHOLDER>
</CONTROLHOLDER>

需要转换为

<CONTROLS>
<CONTROLHOLDER ID="CH1">
    <CONTROL11 ID="ED1">        
    <CONTROL11>
    <CONTROL12 ID="ED2">
    </CONTROL12>
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH2">
    <CONTROL21 ID="ED3">    
    <CONTROL21>
    <CONTROL22 ID="ED4">
    </CONTROL22>    
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH21">
    <CONTROL211 ID="ED5" >
    <CONTROL211>
    <CONTROL212 ID="ED6" >
    </CONTROL212>
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH3">
    <CONTROL31 ID="ED31">   
    <CONTROL31>
    <CONTROL32 ID="ED32">
    </CONTROL32>
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH31">
    <CONTROL311 ID= "ED311">
    <CONTROL311>
    <CONTROL312 ID= "ED312">
    </CONTROL312>           
</CONTROLHOLDER>
<CONTROLHOLDER  ID= "CH313">
    <CONTROL3131 ID= "ED3131">
    <CONTROL3131>
    <CONTROL3132 ID= "ED3132">
    </CONTROL3132>
</CONTROLHOLDER>

1 个答案:

答案 0 :(得分:1)

从身份模板开始处理现有节点的副本

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

然后,您说您想要一个模板将子节点 CONTROLHOLDER 元素移动到其父节点。好吧,只需要一个匹配 CONTROLHOLDER 的模板,然后复制它,以及除了其他 CONTROLHOLDER 元素之外的所有子项。对于任何此类子元素,请在父元素的副本之后复制它们,如此

<xsl:template match="CONTROLHOLDER">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(self::CONTROLHOLDER)]" />
    </xsl:copy>
    <xsl:apply-templates select="CONTROLHOLDER" />
</xsl:template>

请注意,此模板是递归的,因此所有 CONTROLHOLDER 都会“冒泡”到主根元素下。

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="CONTROLHOLDER">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(self::CONTROLHOLDER)]" />
        </xsl:copy>
        <xsl:apply-templates select="CONTROLHOLDER" />
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>