XSLT variable problem

J

Jon Martin Solaas

Hi,

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

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

My xslt looks like this:
--------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
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:eek:utput
method="xml"
version="1.0"
encoding="ISO-8859-1"
indent="yes"/>

<xsl:template match="/">

<xsl:variable name="myNumbers">
<xsl:for-each select="//interestingstuff">
<xsl:sort select="./@number" data-type="number"
order="ascending" />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>

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

The idea is to store a sorted list of interestingstuff-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.
 
M

Martin Honnen

Jon Martin Solaas wrote:

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

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

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

<xsl:variable name="minNumber"
select="$numbers[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.
 
M

mike

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

<xsl:for-each select="//interestingstuff">
<xsl:sort select="./@number" data-type="number"
order="ascending" />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>

is a temporary tree: a document node owning zero or more
interestingStuff 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



Hi,

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

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

My xslt looks like this:
--------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
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:eek:utput
method="xml"
version="1.0"
encoding="ISO-8859-1"
indent="yes"/>

<xsl:template match="/">

<xsl:variable name="myNumbers">
<xsl:for-each select="//interestingstuff">
<xsl:sort select="./@number" data-type="number"
order="ascending" />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>

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

The idea is to store a sorted list of interestingstuff-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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top