XSL根据ID将子项移动到新的父元素

时间:2015-04-11 13:46:12

标签: xml xslt xslt-1.0

有没有办法将孩子移动到一个新的元素,取决于ID,两个级别,取消所有其他内容? 将带有<com>的节点id="something"移动到新节点<ele id="999">中。如果条件不匹配,则不执行任何操作。

初始XML:

<lev0>
 <lev1>
   <ele id="2">
    <lev3>
     <lev4 id="a_dif_thing">
       <com id="">text 1</com>
       <com id="">text 2</com>
     </lev4>
    </lev3>
   </ele>
   <ele id="1">
    <lev3>
     <lev4 id="a_thing">
       <com id="otherthing">text</com>
       <com id="otherthing">text <i>italic</i></com>
       <com id="something"><span>text text</span></com>
     </lev4>
    </lev3>
   </ele>
   <ele>
    <lev3>
     <lev4>
       <com id="">text</com>
     </lev4>
    </lev3>
   </ele>
 </lev1>
</lev0>

输出XML:

<lev0>
 <lev1>
   <ele id="2">
    <lev3>
     <lev4 id="a_dif_thing">
       <com id="">text 1</com>
       <com id="">text 2</com>
     </lev4>
    </lev3>
   </ele>
   <ele id="1">
    <lev3>
     <lev4 id="a_thing">
       <com id="otherthing">text</com>
       <com id="otherthing">text <i>italic</i></com>
     </lev4>
    </lev3>
   </ele>
   <ele id="999">
    <lev3>
     <lev4 id="a_new_thing">
       <com id="something"><span>text text</span></com>
     </lev4>
    </lev3>
   </ele>
   <ele>
    <lev3>
     <lev4>
       <com id="">text</com>
     </lev4>
    </lev3>
   </ele>
 </lev1>
</lev0>

编辑示例以显示每个新<ele>创建的首选位置。

2 个答案:

答案 0 :(得分:0)

我希望这个样式表有所帮助:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output indent="yes" method="xml"/>
    <xsl:strip-space elements="*"/>

    <!-- Identity transform template to copy all nodes and attributes -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- template to process 4th ancestor of com[@id = 'something'] -->
    <xsl:template match="*[*/*/*/com[@id = 'something']]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:apply-templates select="*/*/*/com[@id = 'something']" mode="special"/>
        </xsl:copy>
    </xsl:template>
    <!-- create the element when com[@id = 'something'] is encountered -->
    <xsl:template match="com" mode="special">
        <ele id="999">
            <lev3>
                <lev4 id="a_new_thing">
                    <xsl:copy>
                        <xsl:apply-templates select="@* | node()"/>
                    </xsl:copy>
                </lev4>
            </lev3>
        </ele>
    </xsl:template>
    <!-- do nothing for com[@id = 'something'] elements -->

    <xsl:template match="*/*/*/*/com[@id = 'something']"/>

</xsl:stylesheet>

答案 1 :(得分:0)

---根据您的澄清进行编辑---

以这种方式试试吗?

XSLT 1.0

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

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

<xsl:template match="ele[descendant::com[@id='something']]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    <!-- append a new branch to folow this node-->
        <ele id="999">
            <lev3>
                <lev4 id="a_new_thing">
                    <!-- copy matching nodes -->
                    <xsl:copy-of select="descendant::com[@id='something']"/>
                </lev4>
            </lev3>
        </ele>
</xsl:template>

<!-- suppress moved nodes -->
<xsl:template match="com[@id='something']"/>

</xsl:stylesheet>
相关问题