aw1975
aw1975

Reputation: 1708

XSLT following-sibling unexpected result

Here is my XML:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <employees>
    <region>
      <country>AUS</country>
      <count>1</count>
    </region>
    <region>
      <country>BEL</country>
      <count>0</count>
    </region>
    <region>
      <country>PER</country>
      <count>3</count>
    </region>
    <region>
      <country>ALA</country>
      <count>5</count>
    </region>
  </employees>
</root>

Here is my XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
  <xsl:variable name="map">
  </xsl:variable>
    <xsl:template match="employees">
    <html>
        <body>
          <table>
            <xsl:variable name="regionsWithNonZeroCount" select="region[count &gt; 0]"></xsl:variable>
            <xsl:for-each select="$regionsWithNonZeroCount[position() mod 2 = 1]">
              <tr>
                <td><xsl:value-of select="country"/></td>
                <td><xsl:value-of select="following-sibling::region/country"/></td>   
              </tr>
            </xsl:for-each>
          </table>
      </body>
      </html>
    </xsl:template>
</xsl:stylesheet>

The XSLT should first of all exclude all regions that have don't have a count greater than 0 (i.e. it should exclude BEL) and from the remaining regions it should take two at a time and display them in a table row with two columns, one for each region.

Here is the result I'm expecting:

AUS | PER
-----------
ALA | 

However the actual result is as follows:

AUS | BEL
-----------
ALA | 

Here is an XSLT fiddle demonstrating the issue:

https://xsltfiddle.liberty-development.net/eiZQaGp/9

I don't understand why BEL is being outputted when the regionsWithNonZeroCount variable being iterated over in the xsl:for-each loop shouldn't include BEL. I suspect the following-sibling isn't taking into account the select condition on the regionsWithNonZeroCount variable that should exclude BEL. I don't have much experience with XSLT so any suggestions on how to achieve my desired result would be appreciated.

Upvotes: 2

Views: 58

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

Your suspicion is correct. To get the result you want, try:

<xsl:template match="employees">
    <html>
        <body>
            <table>
                <xsl:variable name="regionsWithNonZeroCount" select="region[count > 0]"/>
                <xsl:for-each select="$regionsWithNonZeroCount[position() mod 2 = 1]">
                    <xsl:variable name="i" select="position()" />
                    <tr>
                        <td>
                            <xsl:value-of select="country"/>
                        </td>
                        <td>
                            <xsl:value-of select="$regionsWithNonZeroCount[2*$i]/country"/>
                        </td>   
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

Upvotes: 1

Related Questions