So you want one column per operator station name, and one row per distinct network name. In XSLT 2.0 this can be done nicely using for-each-group
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:w3="http://www.w3.org" exclude-result-prefixes="w3">
<xsl:template match="/">
<xsl:variable name="allStations"
select="/w3:OperatorStationCollection/w3:OperatorStation" />
<table>
<!-- Header row - two fixed columns plus one per station name -->
<tr>
<td>Name</td><td>Status</td>
<xsl:for-each select="$allStations">
<td><xsl:value-of select="w3:Name" /></td>
</xsl:for-each>
</tr>
<!-- main rows - one per "group" of DataNodeBase elements which share the
same Name -->
<xsl:for-each-group
select="$allStations/w3:Nodes/w3:DataNodeBase"
group-by="w3:Name">
<!-- calculate the column values - the IPAddress if this network (i.e. the
current-group) has an entry for this station, and "None" if not -->
<xsl:variable name="addresses"
select="for $s in ($allStations)
return (current-group()[../.. is $s]/w3:IPAddress, 'None')[1]" />
<tr>
<td><xsl:value-of select="current-grouping-key()" /></td>
<td>
<!-- equal if all the $addresses are the same, unequal otherwise -->
<xsl:value-of select="if (count(distinct-values($addresses)) = 1)
then 'Equal' else 'Unequal'" />
</td>
<xsl:for-each select="$addresses">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
If you're limited to 1.0 then the logic is the same but the stylesheet is much more verbose - you'll have to use the "Muenchian grouping" method to replace for-each-group
, and the equal/unequal calculation is a bit messier because you don't have the distinct-values
function or the capability to define arbitrary sequences of values (the $addresses
variable in the 2.0 version):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:w3="http://www.w3.org" exclude-result-prefixes="w3">
<!-- grouping key to pull out all the DataNodeBase elements with a
particular name -->
<xsl:key name="dnbByName" match="w3:DataNodeBase" use="w3:Name" />
<xsl:template match="/">
<xsl:variable name="allStations"
select="/w3:OperatorStationCollection/w3:OperatorStation" />
<table>
<tr>
<td>Name</td><td>Status</td>
<xsl:for-each select="$allStations">
<td><xsl:value-of select="w3:Name" /></td>
</xsl:for-each>
</tr>
<!-- Muenchian grouping - for-each over a set consisting of just one
DataNodeBase per network name "group" -->
<xsl:for-each select="$allStations/w3:Nodes/w3:DataNodeBase[
generate-id() = generate-id(key('dnbByName', w3:Name)[1])]">
<xsl:variable name="current-group" select="key('dnbByName', w3:Name)" />
<xsl:variable name="current-grouping-key" select="w3:Name" />
<tr>
<td><xsl:value-of select="$current-grouping-key" /></td>
<td>
<xsl:choose>
<!-- "Equal" if all stations have a value for this network name,
and all these values are the same (it is not the case that
any of the values is different from that of the first
station) -->
<xsl:when test="count($current-group) = count($allStations)
and not($current-group/w3:IPAddress
!= $current-group[1]/w3:IPAddress)">
<xsl:text>Equal</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Unequal</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<!-- remaining columns, one per station -->
<xsl:for-each select="$allStations">
<td>
<!-- check whether this station has an address for this network -->
<xsl:variable name="address" select="w3:Nodes/w3:DataNodeBase[
w3:Name = $current-grouping-key]/w3:IPAddress" />
<xsl:choose>
<xsl:when test="$address">
<xsl:value-of select="$address" />
</xsl:when>
<xsl:otherwise>None</xsl:otherwise>
</xsl:choose>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>