如何使用xslt移动xml元素?

时间:2018-03-01 09:19:18

标签: xml xslt

我有以下XML:

<?xml version="1.0" encoding="UTF-8"?> 
<flow xmlns:*** xmlns:xsi=*** xsi:schemaLocation=***> 
    <version>1.0</version> 
    <id>15</id> 
    <date>2018-01-01</date> 
    <sender> 
        <senderId> 
            <idType>G</idType> 
            <idCode>code</idCode> 
        </senderId> 
        <senderName>name</senderName> 
    </sender> 
    <paymentsNumber>2</paymentsNumber> 
    <paymentsTotal>800.40</paymentsTotal> 
    <payment> 
        <paymentId>1</paymentId> 
        <paymentAmount>400.20</paymentAmount> 
        <paymentResult>0</paymentResult> 
        <paymentDate>2018-02-01</paymentDate> 
    </payment> 
    <payment> 
        <paymentId>2</paymentId> 
        <paymentAmount>400.20</paymentAmount> 
        <paymentResult>0</paymentResult> 
        <paymentDate>2018-02-02</paymentDate> 
    </payment> 
</flow>

我必须进入<payment>元素

<version>1.0</version> 
<id>15</id> 
<date>2018-01-01</date>

获取以下xml:

<?xml version="1.0" encoding="UTF-8"?> 
<flow xmlns:*** xmlns:xsi=*** xsi:schemaLocation=***> 
    <sender> 
        <senderId> 
            <idType>G</idType> 
            <idCode>code</idCode> 
        </senderId> 
        <senderName>name</senderName> 
    </sender> 
    <paymentsNumber>2</paymentsNumber> 
    <paymentsTotal>800.40</paymentsTotal> 
    <payment> 
        <version>1.0</version> 
        <id>15</id> 
        <date>2018-01-01</date> 
        <paymentId>1</paymentId> 
        <paymentAmount>400.20</paymentAmount> 
        <paymentResult>0</paymentResult> 
        <paymentDate>2018-02-01</paymentDate> 
    </payment> 
    <payment>
        <version>1.0</version> 
        <id>15</id> 
        <date>2018-01-01</date> 
        <paymentId>2</paymentId> 
        <paymentAmount>400.20</paymentAmount> 
        <paymentResult>0</paymentResult> 
        <paymentDate>2018-02-02</paymentDate> 
    </payment> 
</flow>

如何使用XSLT实现此目标? 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

您需要从identity template开始,它将所有元素按原样复制到输出XML。

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

接下来,<version><id><date>将作为<payment>元素的子项移动。这可以通过在<payment>下复制它们来完成。

<xsl:template match="payment">
    <xsl:copy>
        <xsl:copy-of select="../version | ../id | ../date" />
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

最后,<version>下的<id><date><flow>将被删除,因此请创建一个与这些无效的元素相匹配的模板。

<xsl:template match="version | id | date" />

完整的XSLT如下

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

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="payment">
        <xsl:copy>
            <xsl:copy-of select="../version | ../id | ../date" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="version | id | date" />
</xsl:stylesheet>

输出

<flow>
    <sender>
        <senderId>
            <idType>G</idType>
            <idCode>code</idCode>
        </senderId>
        <senderName>name</senderName>
    </sender>
    <paymentsNumber>2</paymentsNumber>
    <paymentsTotal>800.40</paymentsTotal>
    <payment>
        <version>1.0</version>
        <id>15</id>
        <date>2018-01-01</date>
        <paymentId>1</paymentId>
        <paymentAmount>400.20</paymentAmount>
        <paymentResult>0</paymentResult>
        <paymentDate>2018-02-01</paymentDate>
    </payment>
    <payment>
        <version>1.0</version>
        <id>15</id>
        <date>2018-01-01</date>
        <paymentId>2</paymentId>
        <paymentAmount>400.20</paymentAmount>
        <paymentResult>0</paymentResult>
        <paymentDate>2018-02-02</paymentDate>
    </payment>
</flow>

请注意,这里没有考虑名称空间。在XSLT中,您需要相应地映射这些名称空间。

答案 1 :(得分:0)

去吧:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" version="2.0">

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

    <xsl:template match="flow/version|flow/id|flow/date"/>

    <xsl:template match="flow/version|flow/id|flow/date" mode="change">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="payment">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="preceding-sibling::version" mode="change"/>
            <xsl:apply-templates select="preceding-sibling::id" mode="change"/>
            <xsl:apply-templates select="preceding-sibling::date" mode="change"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>