Merging tables with XSLT

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() &gt; 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?
 
A

Andrew McFarland

Its done using keys.

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


<xsl:key name="rows" match="/data/table[2]/row" use="entry[1]"/>

<xsl:template match="table[position() &gt; 1]"/>

<xsl:template match="row">
<xsl:copy>
<xsl:apply-templates/>
<xsl:copy-of select="key('rows',entry[1])/entry[2]"/>
</xsl:copy>
</xsl:template>

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

</xsl:stylesheet>

Yes, I am replying to my own post. As soon as I'd posted I'd worked
out how to do it. Usenet is my rubber duck today.
 
Joined
Apr 26, 2018
Messages
1
Reaction score
0
how to merge a column having data with empty column in <xsl:value-of,only in model level
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top