Reputation: 23
I have the following XML file that represents a 2D array:
<?xml version="1.0" encoding="UTF-8"?>
<Prop Name='Test' Type='Array' LBound='[0][0]' HBound='[9][9]' ElementType='String' Flags='0x0'>
<Value ID='[0][0]'>1</Value>
<Value ID='[1][0]'>2</Value>
<Value ID='[2][0]'>3</Value>
<Value ID='[0][1]'>10</Value>
<Value ID='[1][1]'>11</Value>
<Value ID='[2][1]'>12</Value>
</Prop>
The first bracketed value in the 'ID' property is the row and the second one the column in the array. The actual number of 'Value' elements in 'Prop' can vary, but I will always have a 2D array.
I need to format this into an HTML table with 2 columns like this one:
For this, I have the following XSLT which basically goes through and prints into the first column all the elements that end in '[0]' and then attempts to find the matching element ending in '[1]':
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Name Value Pairs</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Name</th>
<th style="text-align:left">Value</th>
</tr>
<xsl:for-each select="Prop[@Name='Test']/Value">
<xsl:if test="contains(self::Value/@ID,'][0]')">
<tr>
<td><xsl:value-of select="self::Value"/></td>
<td><xsl:value-of select="parent::Prop/Value[@ID=concat('[',position()-1,'][1]')]"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
This, however, returns the second column empty and the problem seems to be when I try to use the concat function in the @ID property to dynamically change its value.
What am I doing wrong here?
Upvotes: 2
Views: 1038
Reputation: 111541
Given your input XML, this 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="/">
<html>
<body>
<h2>Name Value Pairs</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Name</th>
<th style="text-align:left">Value</th>
</tr>
<xsl:for-each select="Prop[@Name='Test']/Value">
<xsl:if test="contains(@ID,'][0]')">
<xsl:variable name="pos" select="position()"/>
<tr>
<td><xsl:value-of select="."/></td>
<td>
<xsl:value-of select="../Value[@ID=concat('[',$pos - 1,'][1]')]"/>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Will produce this HTML:
<html>
<body>
<h2>Name Value Pairs</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Name</th>
<th style="text-align:left">Value</th>
</tr>
<tr>
<td>1</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>11</td>
</tr>
<tr>
<td>3</td>
<td>12</td>
</tr>
</table>
</body>
</html>
Which renders like this:
Upvotes: 1