A
Andrew McFarland
I've got two tables that I want to merge with XSLT:
<data>
<table>
<row>
<entry>a</entry>
<entry>b</entry>
</row>
<row>
<entry>c</entry>
<entry>d</entry>
</row>
</table>
<table>
<row>
<entry>c</entry>
<entry>c content</entry>
</row>
<row>
<entry>a</entry>
<entry>a content</entry>
</row>
</table>
</data>
I want to merge on the first entry in each row, so the final data
looks like this:
<data>
<table>
<row>
<entry>a</entry>
<entry>b</entry>
<entry>a content</entry>
</row>
<row>
<entry>c</entry>
<entry>d</entry>
<entry>c content</entry>
</row>
</table>
</data>
Whitespace is unimportant.
I can do this with the following XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:template match="table[position() > 1]"/>
<xsl:template match="row">
<xsl:variable name="current_row" select="entry[1]"/>
<xsl:copy>
<xsl:apply-templates/>
<xsl:for-each select="/data/table[2]/row">
<xsl:if test="./entry[1] = $current_row">
<xsl:copy-of select="./entry[2]"/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Although this works, I'm not convinced that it is the most efficient
way of doing things. It would be better (well, it would feel better)
if I looked up the values for the third column of the output using a
hash of some kind, rather than looping over all the rows. Is this
possible in XSLT?
<data>
<table>
<row>
<entry>a</entry>
<entry>b</entry>
</row>
<row>
<entry>c</entry>
<entry>d</entry>
</row>
</table>
<table>
<row>
<entry>c</entry>
<entry>c content</entry>
</row>
<row>
<entry>a</entry>
<entry>a content</entry>
</row>
</table>
</data>
I want to merge on the first entry in each row, so the final data
looks like this:
<data>
<table>
<row>
<entry>a</entry>
<entry>b</entry>
<entry>a content</entry>
</row>
<row>
<entry>c</entry>
<entry>d</entry>
<entry>c content</entry>
</row>
</table>
</data>
Whitespace is unimportant.
I can do this with the following XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:template match="table[position() > 1]"/>
<xsl:template match="row">
<xsl:variable name="current_row" select="entry[1]"/>
<xsl:copy>
<xsl:apply-templates/>
<xsl:for-each select="/data/table[2]/row">
<xsl:if test="./entry[1] = $current_row">
<xsl:copy-of select="./entry[2]"/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Although this works, I'm not convinced that it is the most efficient
way of doing things. It would be better (well, it would feel better)
if I looked up the values for the third column of the output using a
hash of some kind, rather than looping over all the rows. Is this
possible in XSLT?