XSLT将节点复制到一个或多个节点

时间:2018-07-19 15:49:34

标签: xml xslt-1.0

输入XML

<File>
    <Agency>
        <NumericAddress>111</NumericAddress>
        <TransactionCode>A</TransactionCode>
        <Producer>
            <Name>Jane Smith</Name>
        </Producer>
        <Producer>
            <Name>Joe Williams</Name>
        </Producer>
    </Agency>
    <Agency>
        <NumericAddress>222</NumericAddress>
        <TransactionCode>B</TransactionCode>
        <Producer>
            <Name>Susan Jones</Name>
        </Producer>
    </Agency>
</File>

所需的输出

<File>
    <Agency>
        <NumericAddress>111</NumericAddress>
        <TransactionCode>A</TransactionCode>
        <Producer>
            <NumericAddress>111</NumericAddress>
            <Name>Jane Smith</Name>
        </Producer>
        <Producer>
            <NumericAddress>111</NumericAddress>
            <Name>Joe Williams</Name>
        </Producer>
    </Agency>
    <Agency>
        <NumericAddress>222</NumericAddress>
        <TransactionCode>B</TransactionCode>
        <Producer>
            <NumericAddress>222</NumericAddress>
            <Name>Susan Jones</Name>
        </Producer>
    </Agency>
</File>

每个<Agency>节点至少有一个<Producer>,有些节点可能有多个。每个<Agency>节点只有一个<NumericAddress>,每个<Agency>的值都不同。我需要为每个<NumericAddress>复制一个<Agency>节点,并将其放置在每个<Producer>下,如输出XML所示。希望我能正确解释。如何使用XSLT 1.0做到这一点?任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您可以从identity template开始,将输入结构原样复制到输出中。

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

然后将修改Producer节点,并复制其兄弟元素NumericAddress,因为其子元素保留了任何现有的子元素。这可以通过使用<xsl:apply-templates>../ XPath功能来完成,该功能允许从当前节点向上导航一个级别。

<xsl:template match="Producer">
    <xsl:copy>
        <xsl:apply-templates select="../NumericAddress" />
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

完整的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="Producer">
        <xsl:copy>
            <xsl:apply-templates select="../NumericAddress" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出

<File>
    <Agency>
        <NumericAddress>111</NumericAddress>
        <TransactionCode>A</TransactionCode>
        <Producer>
            <NumericAddress>111</NumericAddress>
            <Name>Jane Smith</Name>
        </Producer>
        <Producer>
            <NumericAddress>111</NumericAddress>
            <Name>Joe Williams</Name>
        </Producer>
    </Agency>
    <Agency>
        <NumericAddress>222</NumericAddress>
        <TransactionCode>B</TransactionCode>
        <Producer>
            <NumericAddress>222</NumericAddress>
            <Name>Susan Jones</Name>
        </Producer>
    </Agency>
</File>