Author - Dave Amour

Dave Amour has used computers for as long as he can remember and intially started out as an IT trainer delivering a range of IT courses but for the last 11 years has been focusing on the arena of web application development. He was worked for numerous companies over the years and is currently working for Audacs Software Ltd. Dave is also a keen squash player and an active and sucessful member of Experts Exchange

Please feel free to submit any constructive comments which you can do at the bottom of this page.

Dave may be available for programming tuition or consultancy work. Contact via dave@audacs.co.uk
Dave Amour - Click to view CV 

XSLT following-sibling

Contrary to what you might instinctivley believe, using the following-sibbling:: axis in XSLT does not give you the following sibling. It does in fact give you all the following siblings!

We can prove this be looking at an example. Suppose we have the following xml document:

<?xml version="1.0" encoding="UTF-8"?>
      <People>
            <Person id="1">
                  <Firstname>Dave</Firstname>
                  <Surname>Amour</Surname>
                  <Age>39</Age>
            </Person>
            <Person id="2">
                  <Firstname>Fred</Firstname>
                  <Surname>Bloggs</Surname>
                  <Age>32</Age>
            </Person>
            <Person id="3">
                  <Firstname>Tiffany</Firstname>
                  <Surname>Gallagher</Surname>
                  <Age>31</Age>
            </Person>
            <Person id="4">
                  <Firstname>Will</Firstname>
                  <Surname>Green</Surname>
                  <Age>51</Age>
            </Person>
            <Person id="5">
                  <Firstname>Hilary</Firstname>
                  <Surname>Bloggs</Surname>
                  <Age>28</Age>
            </Person>
      </People>


We will now transform this with some xslt which will attempt to select all People who have a following sibling of Will. Now if this was to evaluate to just the 1 following sibling then we would expect to see just Tiffany. The results we actually get though are Dave Fred And Tiffany. Here is our XSLT: 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="html" encoding="UTF-8" indent="yes"/>
 
      <xsl:template match="//Person[following-sibling::Person/Firstname = 'Will']">
            <xsl:value-of select="Firstname"></xsl:value-of><br/><br/>
      </xsl:template>
 
      <xsl:template match="text()"></xsl:template>
</xsl:stylesheet>
 


This gives us the following results:

Dave<br /><br /> Fred<br /><br /> Tiffany<br /><br />

So this proves that following sibling gives us all following siblings, not just the next one.

Important!

Now the above example also shows something very important. When we use the = operator with a collection of nodes it returns true if the single entity exists anywhere within the collection which of course makes sense if you go back and look at the results of the previous example. We can also prove this with the following experiment,

      <?xml version="1.0" encoding="UTF-8"?>
      <?xml-stylesheet type="text/xsl" href="People.xslt"?>
      <People>
            <Person id="1">
                  <Firstname>Dave</Firstname>
                  <Surname>Amour</Surname>
                  <Age>39</Age>
            </Person>
            <Person id="2">
                  <Firstname>Fred</Firstname>
                  <Surname>Bloggs</Surname>
                  <Age>32</Age>
            </Person>
            <Person id="3">
                  <Firstname>Tiffany</Firstname>
                  <Surname>Gallagher</Surname>
                  <Age>31</Age>
            </Person>
            <Person id="4">
                  <Firstname>Will</Firstname>
                  <Surname>Green</Surname>
                  <Age>51</Age>
            </Person>
            <Person id="5">
                  <Firstname>Hilary</Firstname>
                  <Surname>Bloggs</Surname>
                  <Age>28</Age>
            </Person>
            <Person id="6">
                  <Firstname>Fred</Firstname>
                  <Surname>Green</Surname>
                  <Age>22</Age>
            </Person>
            </People>
 
      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output method="html" encoding="UTF-8" indent="yes"/>
 
            <xsl:template match="/">
                  <h1>Experiment</h1>
 
                  <xsl:variable name="People" select="//Person/Firstname"></xsl:variable>
 
                  <xsl:if test="'Tiffany' = $People">
                        Tiffany exists in People
                  </xsl:if>
 
                  <p>
                        People are as follows
                  </p>
 
                  <xsl:for-each select="$People">
                        <xsl:value-of select="."></xsl:value-of><br/>
                  </xsl:for-each>
            </xsl:template>
      </xsl:stylesheet>


The above transformation gives us the following results proving the theory on how = works:

Experiment

Tiffany exists in Pepole

People are as follows

Dave
Fred
Tiffany
Will
Hilary
Fred
 


It is of course possible to specify just the preceeding sibling - by using an index. If we change our template code as follows:

      <xsl:template match="//Person[following-sibling::Person[1]/Firstname = 'Will']">
            <xsl:value-of select="Firstname"></xsl:value-of><br/><br/>
      </xsl:template>

Then we just get Tiffany as our output. If we changed it to 2 we would get Fred and 3 would give us Dave. We can see therefore that the index collection (for want of a better expression) is like an array with the items in order of proximity to the original node. You can test this by performing the mirror image function and using preceding-sibling as follows:

      <xsl:template match="//Person[preceding-sibling::Person/Firstname = 'Fred']">

            <xsl:value-of select="Firstname"></xsl:value-of><br /><br />

      </xsl:template>


In laymans terms this is saying select all People whose preceding person is Fred. This should and does give us Tiffany, Will and Hilary. Now to test our array proximity theory we should get 1 for Tiffany, 2 for Will and 3 for Hilary. You can try this yourself and see that it does work.

One other point really worth noting is that we have to specify what the sibling is ie we had to but the word Person after the ::

Leave a comment

Name

Email (optional and not disclosed)



Email address is not disclosed but just used to alert you of new posts if entered
Word CV
HTML CV
PDF CV
Text CV
CMS Lite
ETraining
Planet Health
Florida Health
the Date Shack
Taylors
Emcat
Emtex
Browne Jacobson
Alliance & Leicester
Baird Leisure
Swarfega
Creature Comforts
Rugeley Chess Club
Katnip
Katmaid
Dudley NHS
Contact Me
Current Status