Reputation: 1796
I have the following XML and want to copy <itemInformation>
elements to be below <orderLineItem>
elements:
<?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>
I came up with the following 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>
I am expecting this target 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>
But in the second <orderLineItem>
element I am getting the first <itemInformation>
again instead of the second one.
So I have to match <itemInformation>
1, 2,... with <orderLineItem>
1, 2,... I just can't figure out the XPATH I need to use for that.
Upvotes: 0
Views: 50
Reputation: 3262
The right XPath expression is the following:
../extension/orderExtension/itemInformation[normalize-space(text())=normalize-space(current()/text())]
The problem with yours is that you are messing up with the context node, remember that any relative path expression in the predicate (the expression you put between the brackets) refers to the current element, the one that will be picked in case the expression evaluates to true. The current
function is defined by XSLT, and refers to its context element, which is the same context element of the whole XPath (but it changes in the predicates).
I also replaced the parent::order
step with its abbreviated syntax ..
Upvotes: 1