Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 26th, 2009, 06:00 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default Using the position() function...

I have the following in an XML i'm working with

snippet
Code:
<conference name="Eastern" id="1"/>
<division name="Northeast" id="1"/>
<opponent-name name="Rockets" alias="Col"/>
<opponent-city city="Colorado"/>
<opponent-code id="17" global-id="4970"/>
<conference name="Western" id="2"/>
<division name="Northwest" id="6"/>
I'n my xsl i've coded the following to retrieve the nodes/attributes and their values...

Code:
 
<xsl:variable name="nm" select="conference/@name"/>
<xsl:variable name="id" select="conference/@id"/>
  <conference name="{$nm}" id="{$id}"/>&newline;
 
<xsl:variable name="nm" select="division/@name"/>
<xsl:variable name="id" select="division/@id"/>
  <division name="{$nm}" id="{$id}"/>&newline;
 
<xsl:variable name="nm" select="opponent-name/@name"/>
<xsl:variable name="alias" select="opponent-name/@alias"/>
  <opponent-name name="{$nm}" alias="{$alias}"/>&newline;
 
<xsl:variable name="city" select="opponent-city/@city"/>
  <opponent-city city="{$city}"/>&newline;
 
<xsl:variable name="id" select="opponent-code/@id"/>
<xsl:variable name="gid" select="opponent-code/@global-id"/>
  <opponent-code id="{$id}" global-id="{$gid}"/>&newline;<xsl:variable name="confnm" select="conference/@name"/>
<xsl:variable name="confid" select="conference/@id"/>
  <conference name="{$confnm}" id="{$confid}"/>&newline;
<xsl:variable name="divnm" select="division/@name"/>
<xsl:variable name="divid" select="division/@id"/>
  <division name="{$divnm}" id="{$divid}"/>&newline;
The problem that i'm currently hacving is that i keep retrieving the same value for the attributes in both the conference and division nodes in the output.

Code:
<!--current output-->
 
<conference name="Eastern" id="1"/>
<division name="Northeast" id="1"/>
<opponent-name name="Rockets" alias="Col"/>
<opponent-city city="Colorado"/>
<opponent-code id="17" global-id="4970"/>
<conference name="Eastern" id="1"/>
<division name="Northeast" id="1"/>
 
<!-- desired output -->
 
<conference name="Eastern" id="1"/>
<division name="Northeast" id="1"/>
<opponent-name name="Rockets" alias="Col"/>
<opponent-city city="Colorado"/>
<opponent-code id="17" global-id="4970"/>
<conference name="Western" id="2"/>
<division name="Northwest" id="6"/>
Is there a way to use the position() function so that i can retrieve the value of the attributes of the second conference and division? I tried things like:

<xsl:variable name="confnm" select="conference/@name[position=last]"/>
<xsl:variable name="confid" select="conference/@id[position=last]"/>
<conference name="{$confnm}" id="{$confid}"/>&newline;

<xsl:variable name="confnm" select="conference/@id[position=2]"/>
<conference name="{$confnm}" id="{$confid}"/>&newline;

But none of the above seems to work.

Last edited by vb89; August 26th, 2009 at 06:05 PM..
 
Old August 26th, 2009, 06:54 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

You can get the second conference like this

conference[2]/@name

or the last conference like this:

conference[last()]/@name
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old August 26th, 2009, 07:06 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Perfect...thanks mhkay!!
 
Old October 15th, 2009, 11:54 AM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

So to follow up on the original question, I have a very similar question but can't seem to get this working...

In the case i have a for-loop and i'm doing something like this:

Code:
<xsl:for-each select="sample/number">
 
               <xsl:choose>
                <xsl:when test="@number=1">
                  <xsl:variable name="xAns" select="@answer"/>
                    <sample-1 answer="{$xAns}"/>&newline;
                </xsl:when>
                </xsl:choose>
 
               <xsl:choose>
                <xsl:when test="@number=2">
                  <xsl:variable name="xAns" select="@answer"/>
                    <sample-2 answer="{$xAns}"/>&newline;
                </xsl:when>
                </xsl:choose>
etc...
So saying the original XML looks something like this....
Code:
<sample number=1 answer=434/>
<sample number=2 answer=438/>
...
<sample number=5 answer=534/>
<sample number=1 answer=538/> and then the numbering restarts back to one
What I would like to know is how to turn that sample number=1 where the numbering RESTARTS to 6. So I would like it to say
Code:
<sample number=5 answer=534/>
<sample number=6 answer=538/>
<sample number=7 answer=542/>
etc...
I was thinking something like
Code:
               <xsl:choose>
                <xsl:when test="@number=1[2]">
                  <xsl:variable name="xAns" select="@answer"/>
                    <sample-6 answer="{$xAns}"/>&newline;
                </xsl:when>
                </xsl:choose>
But the above doens't seem to work.

Last edited by vb89; October 15th, 2009 at 11:56 AM..
 
Old October 15th, 2009, 12:01 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Can you post a well-formed XML input sample and the corresponding XML output sample you want to create?
And also mention whether you use XSLT 2.0 or 1.0.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old October 15th, 2009, 12:16 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

XSLT: 2.0

Original XML

Code:
<homework>
   <math subjuect=algebra>
     <sample number=1 answer=434/>
     <sample number=2 answer=438/>
     <sample number=3 answer=442/>
     <sample number=4 answer=446/>
     <sample number=5 answer=550/>
     <sample number=1 answer=554/>
     <sample number=2 answer=558/>
     <sample number=3 answer=562/>
     <sample number=4 answer=566/>
     <sample number=5 answer=570/>
  </math>
</homework>
Desired output

Code:
<homework>
   <math subjuect=algebra>
     <sample number=1 answer=434/>
     <sample number=2 answer=438/>
     <sample number=3 answer=442/>
     <sample number=4 answer=446/>
     <sample number=5 answer=550/>
     <sample number=6 answer=554/>
     <sample number=7 answer=558/>
     <sample number=8 answer=562/>
     <sample number=9 answer=566/>
     <sample number=10 answer=570/>
  </math>
</homework>
 
Old October 15th, 2009, 12:32 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

You can simply use xsl:number as follows:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
  <xsl:template match="sample">
    <xsl:copy>
      <xsl:attribute name="number">
        <xsl:number/>
      </xsl:attribute>
      <xsl:attribute name="answer" select="@answer"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old October 15th, 2009, 04:59 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Thanks for the reply Martin but I had one more quesitioin. If i wanted to concat a value to the node, how would i go about this?

Desired output
Code:
<homework>
   <math subjuect=algebra>
     <sample-1 number=1 answer=434/>
     <sample-2 number=2 answer=438/>
     <sample-3 number=3 answer=442/>
     <sample-4 number=4 answer=446/>
     <sample-5 number=5 answer=550/>
     <sample-6 number=6 answer=554/>
     <sample-7 number=7 answer=558/>
     <sample-8 number=8 answer=562/>
     <sample-9 number=9 answer=566/>
     <sample-10 number=10 answer=570/>
  </math>
</homework>

Last edited by vb89; October 15th, 2009 at 05:14 PM..
 
Old October 15th, 2009, 05:29 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>I can think of any conceivable reason for wanting a sequence of elements with names sample-1, sample-2, etc - it looks like a really bad way of using XML. But you can do it with <xsl:element name="sample-{position()}"/>.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
vb89 (October 15th, 2009)
 
Old October 15th, 2009, 05:47 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Yeah i agree this XML is a bit wacky/irregular...regardless you solution did it. Thank you!





Similar Threads
Thread Thread Starter Forum Replies Last Post
POSITION() pallone XSLT 8 June 3rd, 2009 10:04 AM
Position barski XSLT 5 July 11th, 2007 01:54 PM
Passing nodeset into position() function EstherMStrom XSLT 1 May 18th, 2005 04:04 PM
Position: relative; czambran BOOK: Beginning CSS: Cascading Style Sheets for Web Design ISBN: 978-0-7645-7642-3 2 April 7th, 2005 11:22 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.