xslt 将第二个节点下的节点移动到第一个节点并删除第二个节点

xslt to move a node under second node into first node and remove second node

我有 XML 这样的:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<release>
    <changerequest>101</changerequest>
    <morechangerequest />
    <year>1998</year>
</release>
<release>
    <year>1998</year>
    <remarks>
        <remarkname>name</remarkname>
        <remarktitle>remarktitle</remarktitle>
    </remarks>
    <remarks>
        <remarkname>name2</remarkname>
        <remarktitle>remarktitle2</remarktitle>
    </remarks>
    <moreremarks />
</release>
    <othertags />
</root>

我想要这样的输出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<release>
    <changerequest>101</changerequest>
    <morechangerequest/>
    <year>1998</year>
    <remarks>
        <remarkname>name</remarkname>
        <remarktitle>remarktitle</remarktitle>
    </remarks>
    <remarks>
        <remarkname>name2</remarkname>
        <remarktitle>remarktitle2</remarktitle>
    </remarks>
    <moreremarks/>
</release>
    <othertags />
</root>

即把第二个release标签下的remarks标签全部移动到第一个release标签,然后删除第二个release标签。

我使用的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<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:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="@*|//release[1]/*"/>
                    <remarks>
        <xsl:apply-templates select="@*|//release[2]/remarks/*"/>
                    </remarks>
    </xsl:copy>
</xsl:template>
<xsl:template match="//release[2]"/>
</xsl:stylesheet>

它有两个问题:

  1. 它删除了 xml 中除发布标签之外的所有其他内容。
  2. 只保留一个备注标签

有灯吗?谢谢,

move all the remarks tags under the second release tag to first release tag, then delete the second release tag.

这可以按如下方式完成:

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="/root">
    <xsl:copy>
        <release>
            <xsl:apply-templates select="release[1]/*"/>
            <xsl:apply-templates select="release[2]/remarks"/>
            <xsl:apply-templates select="*[not(self::release)]"/>
        </release>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>