XSLT variable problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jon Martin Solaas

    XSLT variable problem

    Hi,

    I have a general document somewhat like this:
    --------------------------------------
    <root>
    <level1>
    <level2>
    <interestingstu ff number="2"/>
    <interestingstu ff number="3"/>
    <interestingstu ff number="1"/>
    </level2>
    <level2>
    <interestingstu ff number="10"/>
    </level2>
    </level1>
    <level1>
    <interestingstu ff number = "11"/>
    </level1>
    </root>
    --------------------------------------

    Now, I want to use the lowest number value from the interestingstuf f
    nodes' number attribute in various places in an xslt transformation.

    My xslt looks like this:
    --------------------------------------
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:styleshe et
    version="2.0"
    xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
    xmlns:xst="http ://www.w3.org/2005/02/xpath-datatypes"
    exclude-result-prefixes="xs fn xdt">

    <xsl:output
    method="xml"
    version="1.0"
    encoding="ISO-8859-1"
    indent="yes"/>

    <xsl:template match="/">

    <xsl:variable name="myNumbers ">
    <xsl:for-each select="//interestingstuf f">
    <xsl:sort select="./@number" data-type="number"
    order="ascendin g" />
    <xsl:copy-of select="."/>
    </xsl:for-each>
    </xsl:variable>

    <xsl:for-each select='root'>
    <MyElement>
    <xsl:attribut e name="TimeStamp ">
    <xsl:value-of select="$myNumb ers[1]/@number"/>
    </xsl:attribute>
    </MyElement>
    </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>
    --------------------------------------

    The idea is to store a sorted list of interestingstuf f-nodes, that may
    occure "anywehre" in the xml, in the myNumbers variable, and then just
    pick the first one to get hold of the lowest number. Running in Altova
    XML Spy this works, but not with Oracle XML or Stylus Studio/Saxon, so I
    suppose the Altova processor is a bit too forgiving and I'm doing
    something illegal. But what?

    Also, as I don't need the whole sorted list of numbers, just the lowest
    one, I should find a way to store only that number in the variable. I
    suppose I'll figure that one out myself, it's spotting the error in the
    stylesheet above I just can't seem to grasp, and I really would like to
    understand what's wrong.

    --
    jon martin solaas
    jon_martin_sola as ¤ y-a-h-o-o...n-o
  • Martin Honnen

    #2
    Re: XSLT variable problem



    Jon Martin Solaas wrote:

    [color=blue]
    > I have a general document somewhat like this:
    > --------------------------------------
    > <root>
    > <level1>
    > <level2>
    > <interestingstu ff number="2"/>
    > <interestingstu ff number="3"/>
    > <interestingstu ff number="1"/>
    > </level2>
    > <level2>
    > <interestingstu ff number="10"/>
    > </level2>
    > </level1>
    > <level1>
    > <interestingstu ff number = "11"/>
    > </level1>
    > </root>
    > --------------------------------------
    >
    > Now, I want to use the lowest number value from the interestingstuf f
    > nodes' number attribute in various places in an xslt transformation.[/color]

    With XSLT 1.0 you could simply do the following in two top level variables

    <xsl:variable name="numbers"
    select="//interestingstuf f/@number" />

    <xsl:variable name="minNumber "
    select="$number s[not (. &gt; $numbers)]" />

    and then use $minMumber where needed.

    I suspect XSLT 2.0/XPath 2.0 even give you functions to find the minimum.


    --

    Martin Honnen

    Comment

    • mike@saxonica.com

      #3
      Re: XSLT variable problem

      Under XSLT 2.0 the value of a variable declared like this:

      <xsl:variable name="myNumbers ">[color=blue]
      > <xsl:for-each select="//interestingstuf f">
      > <xsl:sort select="./@number" data-type="number"
      > order="ascendin g" />
      > <xsl:copy-of select="."/>
      > </xsl:for-each>
      > </xsl:variable>[/color]

      is a temporary tree: a document node owning zero or more
      interestingStuf f elements copied from the source document and sorted.

      When you then do $myNumbers[1]/@number you are trying to select an
      attribute of a document node, but document nodes do not have
      attributes.

      To get the effect you want, add as="element()* " to the xsl:variable -
      the value will then be a sequence of element nodes. You could also use
      xsl:sequence in place of xsl:copy-of to avoid the unnecessary copying
      of the elements.

      If this "works" as written in Altova, then Altova has a bug.

      Michael Kay




      Jon Martin Solaas wrote:[color=blue]
      > Hi,
      >
      > I have a general document somewhat like this:
      > --------------------------------------
      > <root>
      > <level1>
      > <level2>
      > <interestingstu ff number="2"/>
      > <interestingstu ff number="3"/>
      > <interestingstu ff number="1"/>
      > </level2>
      > <level2>
      > <interestingstu ff number="10"/>
      > </level2>
      > </level1>
      > <level1>
      > <interestingstu ff number = "11"/>
      > </level1>
      > </root>
      > --------------------------------------
      >
      > Now, I want to use the lowest number value from the interestingstuf f
      > nodes' number attribute in various places in an xslt transformation.
      >
      > My xslt looks like this:
      > --------------------------------------
      > <?xml version="1.0" encoding="ISO-8859-1"?>
      > <xsl:styleshe et
      > version="2.0"
      > xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
      > xmlns:xs="http://www.w3.org/2001/XMLSchema"
      > xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
      > xmlns:xst="http ://www.w3.org/2005/02/xpath-datatypes"
      > exclude-result-prefixes="xs fn xdt">
      >
      > <xsl:output
      > method="xml"
      > version="1.0"
      > encoding="ISO-8859-1"
      > indent="yes"/>
      >
      > <xsl:template match="/">
      >
      > <xsl:variable name="myNumbers ">
      > <xsl:for-each select="//interestingstuf f">
      > <xsl:sort select="./@number" data-type="number"
      > order="ascendin g" />
      > <xsl:copy-of select="."/>
      > </xsl:for-each>
      > </xsl:variable>
      >
      > <xsl:for-each select='root'>
      > <MyElement>
      > <xsl:attribut e name="TimeStamp ">
      > <xsl:value-of select="$myNumb ers[1]/@number"/>
      > </xsl:attribute>
      > </MyElement>
      > </xsl:for-each>
      > </xsl:template>
      > </xsl:stylesheet>
      > --------------------------------------
      >
      > The idea is to store a sorted list of interestingstuf f-nodes, that may
      > occure "anywehre" in the xml, in the myNumbers variable, and then just
      > pick the first one to get hold of the lowest number. Running in Altova
      > XML Spy this works, but not with Oracle XML or Stylus Studio/Saxon, so I
      > suppose the Altova processor is a bit too forgiving and I'm doing
      > something illegal. But what?
      >
      > Also, as I don't need the whole sorted list of numbers, just the lowest
      > one, I should find a way to store only that number in the variable. I
      > suppose I'll figure that one out myself, it's spotting the error in the
      > stylesheet above I just can't seem to grasp, and I really would like to
      > understand what's wrong.
      >
      > --
      > jon martin solaas
      > jon_martin_sola as ¤ y-a-h-o-o...n-o[/color]

      Comment

      Working...