Reputation: 109
I have an XML doc with two sets of data in it. I need to output a HTML table that combines the data.
The XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<fdata>
<RepairHistory>
<RepairList>
<RepairJob>
<RepairRef>56740408</RepairRef>
<RepairDescription>Baths</RepairDescription>
<RepairReportedDate>20180515</RepairReportedDate>
<RepairCompletedDate></RepairCompletedDate>
<RepairStartDate>20180515</RepairStartDate>
</RepairJob>
<RepairJob>
<RepairRef>56735043</RepairRef>
<RepairDescription>Basins</RepairDescription>
<RepairReportedDate>20180515</RepairReportedDate>
<RepairCompletedDate></RepairCompletedDate>
<RepairStartDate>20180515</RepairStartDate>
</RepairJob>
<RepairJob>
<RepairRef>56740415</RepairRef>
<RepairDescription>Showers</RepairDescription>
<RepairReportedDate>20180515</RepairReportedDate>
<RepairCompletedDate></RepairCompletedDate>
<RepairStartDate>20180515</RepairStartDate>
</RepairJob>
</RepairList>
</RepairHistory>
<map>
<entry>
<string>GUID</string>
<string>be0f53f5-7a09-47cd-9928-0c865b6450a5</string>
</entry>
<entry>
<string>JOBNUMBER</string>
<string>56740408</string>
</entry>
</map>
<map>
<entry>
<string>GUID</string>
<string>5ce2e8fe-7735-4f98-b3a9-3bd386edb338</string>
</entry>
<entry>
<string>JOBNUMBER</string>
<string>56740415</string>
</entry>
</map>
</fdata>
JOBNUMBER has to match RepairRef. Not all of the data at the bottom matches the data at the top. I need to output the data in a table as follows:
Date Ref Details GUID
20180515 56740408 Baths be0f53f5-7a09-47cd-9928-0c865b6450a5
20180515 56735043 Basins No GUID
20180515 56740415 Showers 5ce2e8fe-7735-4f98-b3a9-3bd386edb338
I have tried to output the table using the following xsl, but it doesn't work...
<xsl:template match="/">
<h3>Repair history</h3>
<table>
<tr>
<th>Date</th>
<th>Ref</th>
<th>Details</th>
<th>GUID</th>
</tr>
<xsl:apply-templates select ="//RepairJob" />
</table>
</xsl:template>
<xsl:template match="RepairJob">
<xsl:variable name="JobNumber" select="RepairRef" />
<tr>
<td><xsl:value-of select="RepairStartDate"/></td>
<td><xsl:value-of select="RepairRef"/></td>
<td><xsl:value-of select="RepairDescription"/></td>
<td>
<xsl:choose>
<xsl:when test="count(//map//entry[2]//string[2] = $JobNumber) > 0">
<xsl:value-of select="//map//entry[2]//string[2] = $JobNumber"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>No GUID</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:template>
I can see that I am not selecting the correct node to display, but the matching is not working either. Can anyone help?
Upvotes: 0
Views: 28
Reputation: 70618
Your current xsl:value-of
evaluates to a boolean ("true" or "false"). The expression you actually want is this...
<xsl:value-of select="//map[entry[2]/string[2] = $JobNumber]/entry[1]/string[2]"/>
The xsl:when
needs a tweak too, so the whole xsl:choose
should look like this:
<xsl:choose>
<xsl:when test="//map[entry[2]/string[2] = $JobNumber]">
<xsl:value-of select="//map[entry[2]/string[2] = $JobNumber]/entry[1]/string[2]"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>No GUID</xsl:text>
</xsl:otherwise>
</xsl:choose>
However, consider using a key to look up the guids....
<xsl:key name="map" match="map" use="entry[string[1] = 'JOBNUMBER']/string[2]" />
Then your xsl:value-of
becomes this
<xsl:value-of select="key('map',$JobNumber)/entry[string[1] = 'GUID']/string[2]"/>
Note, this also allows for the entry
elements to be in any order within a map
element (i.e. the JOBNUMBER could be the first entry, and the GUID the second)
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes" />
<xsl:key name="map" match="map" use="entry[string[1] = 'JOBNUMBER']/string[2]" />
<xsl:template match="/">
<h3>Repair history</h3>
<table>
<tr>
<th>Date</th>
<th>Ref</th>
<th>Details</th>
<th>GUID</th>
</tr>
<xsl:apply-templates select ="//RepairJob" />
</table>
</xsl:template>
<xsl:template match="RepairJob">
<xsl:variable name="JobNumber" select="RepairRef" />
<tr>
<td><xsl:value-of select="RepairStartDate"/></td>
<td><xsl:value-of select="RepairRef"/></td>
<td><xsl:value-of select="RepairDescription"/></td>
<td>
<xsl:choose>
<xsl:when test="key('map',$JobNumber)">
<xsl:value-of select="key('map',$JobNumber)/entry[string[1] = 'GUID']/string[2]"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>No GUID</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1