用于将父节点的所有元素移动到子节点的XSLT代码

时间:2017-12-21 05:52:53

标签: xml xslt

我是XSLT编程的新手,希望达到以下效果。

输入XML结构

<?xml version="1.0" encoding="UTF-8"?>
<ns0:External xmlns:ns0="urn:external:document">
<Header></Header>
<Item></Item>
<Item></Item>
<Header></Header>
<Item></Item>
<Item></Item>
</ns0:External>

输出XML结构

<?xml version="1.0" encoding="UTF-8"?>
<ns0:External xmlns:ns0="urn:external:document">
<Header>
   <Item></Item>
   <Item></Item>
</Header>
<Header>
   <Item></Item>
   <Item></Item>
</Header>
</ns0:External>

1 个答案:

答案 0 :(得分:0)

试试这个:

XSLT 2.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="urn:external:document"
    version="2.0">
    <xsl:output indent="yes"></xsl:output>
    <xsl:template match="ns0:External">
        <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="Header">
            <xsl:copy>
                <xsl:apply-templates/>
                <xsl:apply-templates select="current-group()"/>
            </xsl:copy>
        </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

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

    <xsl:template match="Header"/>

</xsl:stylesheet>

请参阅http://xsltransform.net/3MEbY6g/1

处的转化

XSLT 1.0

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

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

    <xsl:template match="Header">
        <xsl:copy>
            <xsl:apply-templates/>
            <xsl:if test="following-sibling::*[1][not(self::Header)]">
                <xsl:call-template name="Wrapper">
                    <xsl:with-param name="Element" select="following-sibling::*[1][not(self::Header)]"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="Wrapper">
        <xsl:param name="Element"/>
        <xsl:copy-of select="$Element"/>
        <xsl:if test="$Element/following-sibling::*[1][not(self::Header)]">
            <xsl:call-template name="Wrapper">
                <xsl:with-param name="Element" select="$Element/following-sibling::*[1][not(self::Header)]"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="Item"/>

</xsl:stylesheet>