Results 1 to 8 of 8

Thread: xslt --> position() function

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Manchester,UK
    Posts
    94

    Unhappy xslt --> position() function

    I'm learning xslt at the moment, I want to use the following as a means to compare a value to the same value on a previous node in a node set.

    <xsl:if test="column[@name='Database Name']/@value!=(//records/record)[string(position()-1)]/column[@name='Database Name']/@value">

    where the data looks a bit like this

    <records>
    <record>
    <column name="Database Name" value="DB1"/>
    </record>
    <record>
    <column name="Database Name" value="DB2"/>
    </record>
    </records>

    Unfortunately the bit where I refer to position() - 1 doesn't work. using a value-of on it's own will output it as text and sometimes it will display something (usually the first node) but it can't do the comparison.

    HELP!!!

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    What is the string() for?

    Maybe you could use a different axis to access the previous sibling.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Manchester,UK
    Posts
    94
    The string was left over from something I was testing, I was trying to force it to calculate the index before using it in the pattern. Didn't work either way.

    I've noticed some threads about a method of grouping in xslt but I'd rather not go down that route yet.

    I would use axis if I knew how, I've tried

    test="column[@name='Database Name']/@value!=preceding-sibling::column[@name='Database Name']/@value"

    and also just the preceding axis but no luck. It's so difficult to debug.

    I am probably doing something in the wrong way but can't find what it is.

    All I want is to compare to the previous node !!!

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I think you have a problem with the reference node. Can you post the complete template rule?
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Manchester,UK
    Posts
    94
    The data in a more complete form is as follows

    <taskresults>
    <summary>
    <title>Database Sizes</title>
    <date>2004-01-15 05:00:22</date>
    <server>xyz</server>
    <screenwidth>640</screenwidth>
    </summary>
    <records>
    <record>
    <column name="Task Name" value="Database Sizes" />
    <column name="Server Name" value="xyz" />
    <column name="Database Name" value="gcmsystem" />
    <column name="File Logical Name" value="GCMSystem31 " />
    <column name="File Disk Name" value="e:\data\gcmsystem.mdf" />
    <column name="File Number" value="1" />
    <column name="File Type" value="Data File" />
    <column name="Date Collected" value="15/01/2004 05:14:16" />
    <column name="Data Size" value="27.460937" />
    <column name="Data Size Percent" value="0.8107" />
    <column name="Index Size" value="2.234375" />
    <column name="Index Size Percent" value="0.0660" />
    <column name="Other Size" value="0.828125" />
    <column name="Other Size Percent" value="0.0244" />
    <column name="Percent Free" value="0.0989" />
    <column name="File Size" value="33.875" />
    </record>
    <record>
    <column name="Task Name" value="Database Sizes" />
    <column name="Server Name" value="xyz" />
    <column name="Database Name" value="gcmsystem" />
    <column name="File Logical Name" value="GCMSystem31_log " />
    <column name="File Disk Name" value="e:\data\gcmsystem_log.ldf" />
    <column name="File Number" value="2" />
    <column name="File Type" value="Log File" />
    <column name="Date Collected" value="15/01/2004 05:14:16" />
    <column name="Data Size" value="27.460937" />
    <column name="Data Size Percent" value="0.1166" />
    <column name="Index Size" value="2.234375" />
    <column name="Index Size Percent" value="0.0095" />
    <column name="Other Size" value="0.828125" />
    <column name="Other Size Percent" value="0.0035" />
    <column name="Percent Free" value="0.8704" />
    <column name="File Size" value="235.5625" />
    </record>
    </records>
    </taskresults>

    and the current style sheet is

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
    <HTML>
    <link rel="stylesheet" type="text/css" href="style.css"/>
    <BODY>
    <xsl:for-each select="//records/record">
    <xsl:choose>
    <xsl:when test="position()=1">
    <xsl:value-of disable-output-escaping="yes" select="'&lt;div class=tr_main&gt;'"/>
    <div class="tr_title">Database file statistics for database <xsl:value-of select="column[@name='Database Name']/@value"/> on server <xsl:value-of select="//summary/server"/></div>
    <div class="tr_collect_date"><xsl:value-of select="//summary/date"/></div>
    <br/>
    </xsl:when>
    <xsltherwise>
    <xsl:if test="column[@name='Database Name']/@value!=//records/record[position()-1]/column[@name='Database Name']/@value">
    <xsl:value-of disable-output-escaping="yes" select="'&lt;/div&gt;'"/>
    </xsl:if>
    <xsl:value-of disable-output-escaping="yes" select="'&lt;div class=tr_main&gt;'"/>
    <div class="tr_title">Database file statistics for database <xsl:value-of select="column[@name='Database Name']/@value"/> on server <xsl:value-of select="//summary/server"/></div>
    <div class="tr_collect_date"><xsl:value-of select="//summary/date"/></div>
    <br/>
    </xsltherwise>
    </xsl:choose>
    <xsl:if test="position()=last()">
    <xsl:value-of disable-output-escaping="yes" select="'&lt;/div&gt;'"/>
    </xsl:if>
    </xsl:for-each>
    </BODY>
    </HTML>
    </xsl:template>
    </xsl:stylesheet>




    I'm probably going to rewrite it this morning but any help is greatly appreciated.
    Last edited by London75; Jan 16th, 2004 at 05:00 AM.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Apr 2002
    Location
    Manchester,UK
    Posts
    94
    Ok, heere goes in case anyone does a search, looks like this is a topic that everyone takes a while to get.

    Below is the working XSLT but here is what happened.

    The key (pardon the pun) to working this out was finally understanding what the key() function did and what the muenchian method involves.

    If you look below, the key is an index of all records based on their database name.

    The next step is to do a for-each identifying the first record in each group.

    Then finally for each first record in the group, go back into the key() and get the rest for that group.

    Works a treat

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="databases" match="record" use="column[@name='Database Name']/@value"/>
    <xsl:template match="/">
    <HTML>
    <link rel="stylesheet" type="text/css" href="style.css"/>
    <BODY>
    <xsl:for-each select="//records/record[generate-id(.)=generate-id(key('databases',column[@name='Database Name']/@value))]">
    <xsl:element name="div">
    <xsl:attribute name="class">tr_main</xsl:attribute>
    <div class="tr_title">Database file statistics for database <xsl:value-of select="column[@name='Database Name']/@value"/> on server <xsl:value-of select="//summary/server"/></div>
    <div class="tr_collect_date"><xsl:value-of select="//summary/date"/></div>
    <br/>
    <xsl:for-each select="key('databases',column[@name='Database Name']/@value)">
    <xsl:value-of select="column[@name='Database Name']/@value"/>
    </xsl:for-each>
    </xsl:element>
    <br/>
    </xsl:for-each>
    </BODY>
    </HTML>
    </xsl:template>
    </xsl:stylesheet>


    PS Thanks for your input CornedBee

  7. #7
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654
    Ah, thanks! I happened to be looking for exact the same and been working on this for two days. Well, nearly the same

    Thanks for posting to solution!


    Edit My results look like this: http://merri.net/maaya/songs.xml
    Last edited by Merri; Jan 16th, 2004 at 11:28 AM.

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Nice. Wouldn't ever have come up with something like this.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width