如何使用xslt移动xml元素?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用xslt移动xml元素?相关的知识,希望对你有一定的参考价值。

我有以下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实现这一目标?任何帮助将不胜感激!

答案

您需要从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中,您需要相应地映射这些名称空间。

另一答案

去吧:

<?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>

以上是关于如何使用xslt移动xml元素?的主要内容,如果未能解决你的问题,请参考以下文章

将 XSLT 转换的 XML 片段写入 XMLStreamWriter

如何使用 XSLT 从 XML 中删除元素标记

如何使用 XSLT 将单个子 xml 元素转换为 Json 数组

如何使用带条件的 XSLT 映射在 XML 中移动节点

如何使用 XSLT 替换 XML 节点名称中的字符 - 更改根元素

如何使用带有样式表和 xsltproc 的 xslt 从 xml 中删除元素?