如何使用XSLT同时移动XML元素并添加子元素?

时间:2016-07-22 13:25:48

标签: xml xslt

我在这里要完成的是移动一个元素(包括它的子节点),然后在该元素中添加一个子节点,反之亦然。似乎我一次只能做一件事。可以同时做两件事吗?

这是我的输入xml

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <box1>
        <cd1>
            <title>Title 1</title>
            <artist>Bob Dylan</artist>
            <year>1985</year>
        </cd1>
        <cd2>
            <title>Title 2</title>
            <artist>Bonnie Tyler</artist>
            <year>1988</year>
        </cd2>
    </box1>
    <box2>
        <cd3>
            <title>Title 3</title>
            <artist>Metallica</artist>
        </cd3>
    </box2>
</catalog>

希望得到像这样的输出

<catalog>
<box1>
    <cd1>
        <title>Title 1</title>
        <artist>Bob Dylan</artist>
        <year>1985</year>
    </cd1>
    <cd2>
        <title>Title 2</title>
        <artist>Bonnie Tyler</artist>
        <year>1988</year>
    </cd2>
    <cd3>
        <title>Title 3</title>
        <artist>Metallica</artist>
        <year>1990</year>
    </cd3>
</box1>

正如您所见,元素cd3已移动,并且还添加了子节点。

这就是我所做的以及所有它只是移动元素而不管我放置代码的顺序。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.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="*"/>

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

    <!-- add a child element -->
    <xsl:template match="cd3">
        <xsl:copy>
            <xsl:apply-templates/>
            <year>1990</year>
        </xsl:copy>
    </xsl:template>

    <!-- move node -->
    <xsl:template match="/catalog">
        <xsl:copy>
                <xsl:apply-templates />
                <xsl:copy-of select="box2/cd3"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="box2"/>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

<xsl:copy-of select="box2/cd3"/>更改为<xsl:apply-templates select="box2/cd3"/>并将<xsl:template match="/catalog">更改为<xsl:template match="/catalog/box1">

答案 1 :(得分:0)

我通过以下代码解决了问题。感谢您的帮助让我开始进一步调查。

<xsl:template match="/catalog">
    <xsl:copy>
        <box1>
            <xsl:apply-templates />
            <xsl:apply-templates select="box2/cd3"/>
        </box1>
    </xsl:copy>
</xsl:template>