 |
| 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
|
|
|
|

February 16th, 2009, 11:46 AM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
Need to build a general sequence of integers
Hi,
I'm using Saxon9b
I have need to perform a task similar to: for i = 1 to n
and do some work with each value of i
the value n is to be derived from TL1Position data in my XML file. There are multiple TL1Positions, I need the one with the largest value:
Code:
<xsl:variable name="n">
<xsl:value-of select="max($repoSection//ratttable/rattrow//TL1Position[ancestor::rattrow//TL1Block = 2])"></xsl:value-of>
</xsl:variable>
$n is being set to a number such as 5 or 10 as I expected, but when I've tried using $n the for operator:
for $i in 1 to $n return $i
I get an error
Code:
$ ./buildNMIS TEST
Building NMIS from Repository / Implementation
Target AID Type: TEST
Repository Dir: ../Repository
Implementation Dir: ../Implementation
Validation error at xsl:value-of on line 890 of file:/d:/mphare/SWTools/Projects/RepositoryPOCs/NMIRepoPOC/Scripts/GenNMIS.xsl:
FORG0001: Cannot convert zero-length string to an integer
Transformation failed: Run-time errors were reported
If I set $n to a constant
Code:
<xsl:variable name="n" select="5"></xsl:variable>
It works fine.
What is max() returning if it's not a constant value (or at least something that can be used as a constant in this manner)?
Thanks
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
Last edited by mphare; February 16th, 2009 at 12:02 PM..
|
|

February 16th, 2009, 12:03 PM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Does it work with
Code:
<xsl:variable name="n" select="max($repoSection//ratttable/rattrow//TL1Position[ancestor::rattrow//TL1Block = 2])"/>
?
If not then you need to show the relevant XML input, max() only returns an empty sequence I think if the input sequence is empty.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

February 16th, 2009, 12:14 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I suspect that the path expression used as the argument to max() is selecting nothing. But even if it selecting something, you will need to convert the value to an integer, which you can do using the constructor function xs:integer()
__________________
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:
|
|
|

February 16th, 2009, 12:15 PM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
Hi Martin,
That was the first thing I thought of.
If I remove the 'for' statement (so it compiles) and output the value of $n,
Code:
<xsl:text>Max Position : </xsl:text>
<xsl:variable name="maxPos">
<xsl:value-of select="max($repoSection//ratttable/rattrow//TL1Position[ancestor::rattrow//TL1Block = 2])"></xsl:value-of>
</xsl:variable>
<xsl:value-of select="$maxPos"></xsl:value-of>
I get
Code:
<SyntaxContainer>
<SyntaxHeading/>
<Syntax>ED-TEST:[<TID>]:Max Position: 1<P1-1>:<CTAG>:Max Position :
3[<P2-1>],[<P2-2>]:[<P3-1>],[<P3-2>]:[<KEYWORD=DOMAIN>]:,[<P5-3>];</Syntax>
</SyntaxContainer>
Notice the Max Positions in the output. I'm getting 1 and 3, which are the values I expect to be getting.
Here's a fragment of the input XML. It's part of a large table (ratttable) in a collection ($repoSection). There is only one ratttable in this repoSection. There can be any number of rattrows that have TL1Block=2 each with their own TL1Position value, could be repeated, could be missing values (such as 1 and 3, but no 2 as shown below)
Code:
<rattrow attrfield = "4">
<rattcell format = "Small" colname = "1"><TL1Instance>0001</TL1Instance></rattcell>
<rattcell format = "Small" colname = "2"><TL1Attribute attrType = "Positional">P2-1</TL1Attribute></rattcell>
<rattcell format = "Small" colname = "3"><TL1Domain><IPv4></TL1Domain></rattcell>
<rattcell format = "Small" colname = "4"><TL1Default></TL1Default></rattcell>
<rattcell format = "Tight" colname = "5"><TL1Commands cmdType = "Create">Y</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "6"><TL1Commands cmdType = "Modify">Y</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "7"><TL1Commands cmdType = "Delete">N</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "8"><TL1Commands cmdType = "RetrieveIn">M</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "9"><TL1Commands cmdType = "RetrieveOut">N</TL1Commands></rattcell>
<rattcell format = "Small" colname = "10"></rattcell>
<rattcell format = "Small" colname = "11"><TL1Block>2</TL1Block></rattcell>
<rattcell format = "Small" colname = "12"><TL1Position>1</TL1Position></rattcell>
<rattcell format = "Small" colname = "13"><RespTL1Block>0</RespTL1Block></rattcell>
<rattcell format = "Small" colname = "14"><RespTL1Position>0</RespTL1Position></rattcell>
</rattrow>
<rattrow attrfield = "4">
<rattcell format = "Small" colname = "1"><TL1Instance>0001</TL1Instance></rattcell>
<rattcell format = "Small" colname = "2"><TL1Attribute attrType = "Positional">P2-2</TL1Attribute></rattcell>
<rattcell format = "Small" colname = "3"><TL1Domain>N|Y</TL1Domain></rattcell>
<rattcell format = "Small" colname = "4"><TL1Default>N</TL1Default></rattcell>
<rattcell format = "Tight" colname = "5"><TL1Commands cmdType = "Create">Y</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "6"><TL1Commands cmdType = "Modify">Y</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "7"><TL1Commands cmdType = "Delete">N</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "8"><TL1Commands cmdType = "RetrieveIn">Y</TL1Commands></rattcell>
<rattcell format = "Tight" colname = "9"><TL1Commands cmdType = "RetrieveOut">N</TL1Commands></rattcell>
<rattcell format = "Small" colname = "10"></rattcell>
<rattcell format = "Small" colname = "11"><TL1Block>2</TL1Block></rattcell>
<rattcell format = "Small" colname = "12"><TL1Position>3</TL1Position></rattcell>
<rattcell format = "Small" colname = "13"><RespTL1Block>0</RespTL1Block></rattcell>
<rattcell format = "Small" colname = "14"><RespTL1Position>0</RespTL1Position></rattcell>
</rattrow>
Thanks for taking a look!
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
|
|

February 16th, 2009, 12:58 PM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
Hi Michael,
I've added xs:integer into the constructor, now I get an error that it can't convert an empty string.
So, the max() statement isn't selecting anything.
In that case, I'm not sure how it's outputting the 3 as in 'Max Position : 3' in the above output example.
I'm obviously missing something fundamental.
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
|
|

February 16th, 2009, 01:22 PM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
I am not able to find the problem in those snippets you have posted. Try to isolate the problem to a small but complete test case, then if that does not help to find the problem yourself, post that test case here.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
|
|

February 16th, 2009, 03:36 PM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
I tried a slightly different route to solve the problem.
Code:
<xsl:variable name="rattRows">
<xsl:for-each select="$repoSection//ratttable/rattrow[.//TL1Block = 2]">
<xsl:sort select=".//TL1Position"/>
<ROW>
<xsl:value-of select=".//TL1Position"/>
</ROW>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="maxPos" as="xs:integer">
<xsl:value-of select="$rattRows//ROW[last()]"></xsl:value-of>
</xsl:variable>
<xsl:value-of select="$maxPos"></xsl:value-of>
But my results are the same. All indications are the table search is returning nothing and the convert with xs:integer is failing.
Code:
$ ./buildNMIS TEST
Building NMIS from Repository / Implementation
Target AID Type: TEST
Repository Dir: ../Repository
Implementation Dir: ../Implementation
Validation error at xsl:value-of on line 902 of file:/d:/mphare/SWTools/Projects/RepositoryPOCs/NMIRepoPOC/Scripts/GenNMIS.xsl:
FORG0001: Cannot convert zero-length string to an integer
Transformation failed: Run-time errors were reported
Yet, if I remove the xs:integer, the value of 3 is written to the result.
Code:
<SyntaxContainer>
<SyntaxHeading/>
<Syntax>ED-TEST:[<TID>]:Max Position:
1<P1-1>:<CTAG>:3[<P2-1>],[<P2-2>]:[<P3-1>],[<P3-2>]:[<KEYWORD=DOMAIN>]:,[<P5-3>];</Syntax>
</SyntaxContainer>
Is 3 not a string?
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
Last edited by mphare; February 16th, 2009 at 03:38 PM..
|
|

February 17th, 2009, 11:01 AM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
Hi Martin,
I did as you suggested:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Chapter>
<Section>
<Table>
<Row>
<Block>1</Block>
<Position>1</Position>
</Row>
<Row>
<Block>1</Block>
<Position>2</Position>
</Row>
<Row>
<Block>1</Block>
<Position>3</Position>
</Row>
<Row>
<Block>2</Block>
<Position>1</Position>
</Row>
<Row>
<Block>2</Block>
<Position>5</Position>
</Row>
<Row>
<Block>2</Block>
<Position>3</Position>
</Row>
<Row>
<Block>2</Block>
<Position>4</Position>
</Row>
<Row>
<Block>3</Block>
<Position>1</Position>
</Row>
<Row>
<Block>3</Block>
<Position>2</Position>
</Row>
<Row>
<Block>3</Block>
<Position>3</Position>
</Row>
</Table>
</Section>
</Chapter>
</Root>
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="xml" version="1.1"/>
<xsl:variable name="implSubTree" select="collection(concat('.','/?select=*.xml'))"/>
<!--
=========================================================
-->
<xsl:template match="/">
<xsl:apply-templates select="$implSubTree//Section"/>
</xsl:template>
<!--
=========================================================
-->
<xsl:template match="Section">
<xsl:variable name="Section" select="."/>
<xsl:variable name="Block" select="2"/>
<xsl:variable name="maxPos">
<xsl:value-of select="max($Section//Row/Position[ancestor::Row/Block=$Block])"/>
</xsl:variable>
<xsl:text>
</xsl:text>
<xsl:text>Block: </xsl:text>
<xsl:value-of select="$Block"/>
<xsl:text>
</xsl:text>
<xsl:text>Max Pos: </xsl:text>
<xsl:value-of select="$maxPos"/>
<xsl:for-each select="1 to $maxPos">
<xsl:text>
</xsl:text>
<xsl:text>Seq: </xsl:text>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
It works like a charm.
Does exactly what I needed.
So I'm pretty sure my logic is sound, it must me something to do with the data I'm feeding the script.
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
Last edited by mphare; February 17th, 2009 at 11:14 AM..
|
|

February 17th, 2009, 11:32 AM
|
|
Friend of Wrox
|
|
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
|
|
Found It!
The line:
$repoSection//ratttable/rattrow//TL1Position[.//TL1Block = 2]
is incorrect per my data structure.
It should have been:
$repoSection//ratttable//rattrow//TL1Position[.//TL1Block = 2]
Thanks for all the help!
__________________
------------------------
Keep Moving Forward
GnuPG Key fingerprint = 1AD4 726D E359 A31D 05BF ACE5 CA93 7AD5 D8E3 A876
Michael Hare
|
|
 |