复制具有匹配位置编号的子节点

时间:2014-01-20 19:48:55

标签: xslt xpath xslt-1.0

我有以下XML,并希望将<itemInformation>元素复制到<orderLineItem>元素下面:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<order>
    <orderLineItem>1
        <requestedQuantity>
            <value>2</value>
        </requestedQuantity>
        <tradeItemIdentification>
            <gtin>07610400013192</gtin>
        </tradeItemIdentification>
    </orderLineItem>
    <orderLineItem>2
        <requestedQuantity>
            <value>1</value>
        </requestedQuantity>
        <tradeItemIdentification>
            <gtin>07610400014632</gtin>
        </tradeItemIdentification>
    </orderLineItem>
    <extension>
        <orderExtension>
            <itemInformation>1
                <tradeItemIdentification>
                    <gtin>07610400013192</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
            <itemInformation>2
                <tradeItemIdentification>
                    <gtin>07610400014632</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
        </orderExtension>
    </extension>
</order>
</Envelope>

我提出了以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

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

<xsl:template match="order/orderLineItem">
    <xsl:copy>
        <xsl:apply-templates select="@*" />

        <xxxx>
            <xsl:apply-templates select="parent::order/extension/orderExtension/itemInformation
                [normalize-space(text())=normalize-space(ancestor::order/orderLineItem/text())]"/>
        </xxxx>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

我期待这个目标XML:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<order>
    <orderLineItem>
        <xxxx>
            <itemInformation>1
                <tradeItemIdentification>
                    <gtin>07610400013192</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
        </xxxx>1
        <requestedQuantity>
            <value>2</value>
        </requestedQuantity>
        <tradeItemIdentification>
            <gtin>07610400013192</gtin>
        </tradeItemIdentification>
    </orderLineItem>
    <orderLineItem>
        <xxxx>
            <itemInformation>2
                <tradeItemIdentification>
                    <gtin>07610400014632</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
        </xxxx>2
        <requestedQuantity>
            <value>1</value>
        </requestedQuantity>
        <tradeItemIdentification>
            <gtin>07610400014632</gtin>
        </tradeItemIdentification>
    </orderLineItem>
    <extension>
        <orderExtension>
            <itemInformation>1
                <tradeItemIdentification>
                    <gtin>07610400013192</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
            <itemInformation>2
                <tradeItemIdentification>
                    <gtin>07610400014632</gtin>
                </tradeItemIdentification>
                <grossCost>
                    <currencyCode>
                        <currencyISOCode>ZAR</currencyISOCode>
                    </currencyCode>
                    <monetaryAmount>243.60</monetaryAmount>
                </grossCost>
            </itemInformation>
        </orderExtension>
    </extension>
</order>
</Envelope>

但是在第二个<orderLineItem>元素中,我再次获得第一个<itemInformation>而不是第二个<itemInformation>。 所以我必须将<orderLineItem> 1,2,...与{{1}} 1,2匹配......我只是想不出我需要使用的XPATH。

1 个答案:

答案 0 :(得分:1)

正确的XPath表达式如下:

../extension/orderExtension/itemInformation[normalize-space(text())=normalize-space(current()/text())]

你的问题是你搞乱了上下文节点,记住谓词中的任何相对路径表达式(放在括号之间的表达式)引用当前元素,即将被选中的元素表达式的计算结果为true。 current函数由XSLT定义,并引用其上下文元素,该元素与整个XPath的上下文元素相同(但它在谓词中更改)。

我还用缩写语法parent::order

替换了..步骤