The input xml is sorted by each element's id and I am going through and checking if the current node has the same id as the preceding sibling. If they are the same, then I would like to remove(not display) the current node from the xml and add some of its values to that sibling. It would be very helpful, to check the current node against any previous node and perform the same logic if the ids match.
Here is input xml:
<?xml version="1.0"?>
<transactions>
<transaction>
<name>Test Entry</name>
<id>123</id>
<line_memo>memo1</line_memo>
<amount>5</amount>
</transaction>
<transaction>
<name>Test 1</name>
<id>123</id>
<line_memo>memo2</line_memo>
<amount>10</amount>
</transaction>
<transaction>
<name>Test 2</name>
<id>123</id>
<line_memo>memo3</line_memo>
<amount>15</amount>
</transaction>
<transaction>
<name>Test 3</name>
<id>1235</id>
<line_memo>0123456789</line_memo>
<amount>30</amount>
</transaction>
</transactions>
MY XSLT - I have been experimenting with apply templates and params.:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="transactions">
<transactions>
<xsl:for-each select="transaction">
<xsl:variable name="name" select="adjustment_flag"/>
<xsl:variable name="id" select="id"/>
<xsl:variable name="amount" select="amount"/>
<xsl:variable name="line_memo" select="control_amount"/>
<xsl:variable name="invoice_date" select="invoice_number"/>
<xsl:choose>
<xsl:when test="(position() > 1)">
<xsl:choose>
<xsl:when test="preceding-sibling::transaction[id = $id]">
<transaction>
<xsl:apply-templates select="preceding-sibling::transaction/line_memo">
<xsl:with-param name="newMemo" select="line_memo"/>
</xsl:apply-templates>
<xsl:apply-templates select="preceding-sibling::transaction/amount">
<xsl:with-param name="newAmount" select="amount"/>
</xsl:apply-templates>
<name><xsl:value-of select="name"/></name>
<id><xsl:value-of select="id"/></id>
<!--<line_memo><xsl:value-of select="line_memo"/></line_memo>
<amount><xsl:value-of select="amount"/></amount>-->
</transaction>
</xsl:when>
<xsl:otherwise>
<transaction>
<name><xsl:value-of select="name"/></name>
<id><xsl:value-of select="id"/></id>
<line_memo><xsl:value-of select="line_memo"/></line_memo>
<amount><xsl:value-of select="amount"/></amount>
</transaction>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<transaction>
<name><xsl:value-of select="name"/></name>
<id><xsl:value-of select="id"/></id>
<line_memo><xsl:value-of select="line_memo"/></line_memo>
<amount><xsl:value-of select="amount"/></amount>
</transaction>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</transactions>
</xsl:template>
<xsl:template match="line_memo">
<xsl:param name="newMemo"/>
<new_memo><xsl:value-of select="concat(line_memo, '|', $newMemo)"/></new_memo>
</xsl:template>
<xsl:template match="amount">
<xsl:param name="newAmount"/>
<new_amount><xsl:value-of select="amount + $newAmount"/></new_amount>
</xsl:template>
</xsl:stylesheet>
Desired Output:
<?xml version="1.0"?>
<transactions>
<transaction>
<name>Test Entry</name>
<id>123</id>
<line_memo>memo1|memo2|memo3</line_memo>
<amount>30</amount>
</transaction>
<transaction>
<name>Test 3</name>
<id>1235</id>
<line_memo>0123456789</line_memo>
<amount>30</amount>
</transaction>
</transactions>
My output using above style sheet:
<?xml version="1.0" encoding="utf-16"?>
<transactions>
<transaction>
<name>Test Entry</name>
<id>123</id>
<line_memo>memo1</line_memo>
<amount>5</amount>
</transaction>
<transaction>
<new_memo>|memo2</new_memo>
<new_amount>NaN</new_amount>
<name>Test 1</name>
<id>123</id>
</transaction>
<transaction>
<new_memo>|memo3</new_memo>
<new_memo>|memo3</new_memo>
<new_amount>NaN</new_amount>
<new_amount>NaN</new_amount>
<name>Test 2</name>
<id>123</id>
</transaction>
<transaction>
<name>Test 3</name>
<id>1235</id>
<line_memo>0123456789</line_memo>
<amount>30</amount>
</transaction>
</transactions>
The final output having one element with the 123
id and adding up the amounts and concatenating the memo fields with a |
delimiter.
In my style sheet, I add the apply-templates but I get an error, it says
Required item type of @select attribute of xsl:apply-templates is node(); supplied value has item type xs:string
.
How can I modify the preceding sibling elements and omit the current node?