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 February 16th, 2009, 11:46 AM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Default 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..
 
Old February 16th, 2009, 12:03 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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
 
Old February 16th, 2009, 12:14 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

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:
mphare (February 17th, 2009)
 
Old February 16th, 2009, 12:15 PM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Thumbs up

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:[&lt;TID&gt;]:Max Position: 1&lt;P1-1&gt;:&lt;CTAG&gt;:Max Position :
3[&lt;P2-1&gt;],[&lt;P2-2&gt;]:[&lt;P3-1&gt;],[&lt;P3-2&gt;]:[&lt;KEYWORD=DOMAIN&gt;]:,[&lt;P5-3&gt;];</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>&lt;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
 
Old February 16th, 2009, 12:58 PM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Default

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
 
Old February 16th, 2009, 01:22 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

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:
mphare (February 17th, 2009)
 
Old February 16th, 2009, 03:36 PM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Default

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:[&lt;TID&gt;]:Max Position:
                            1&lt;P1-1&gt;:&lt;CTAG&gt;:3[&lt;P2-1&gt;],[&lt;P2-2&gt;]:[&lt;P3-1&gt;],[&lt;P3-2&gt;]:[&lt;KEYWORD=DOMAIN&gt;]:,[&lt;P5-3&gt;];</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..
 
Old February 17th, 2009, 11:01 AM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Default

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>&#x0a;</xsl:text>
        <xsl:text>Block: </xsl:text>
        <xsl:value-of select="$Block"/>
        <xsl:text>&#x0a;</xsl:text>
        <xsl:text>Max Pos: </xsl:text>
        <xsl:value-of select="$maxPos"/>

        <xsl:for-each select="1 to $maxPos">
            <xsl:text>&#x0a;</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..
 
Old February 17th, 2009, 11:32 AM
Friend of Wrox
 
Join Date: May 2004
Posts: 109
Thanks: 18
Thanked 0 Times in 0 Posts
Default

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





Similar Threads
Thread Thread Starter Forum Replies Last Post
Unsigned integers AndrewH Java Basics 1 September 26th, 2006 02:46 PM
Integers in SQL Server tconlan25 SQL Server 2000 3 August 23rd, 2005 10:08 AM
getting Integers from the query string TadReeves JSP Basics 2 March 16th, 2005 01:22 PM
Using integers with text boxes clojinted General .NET 1 February 19th, 2005 08:12 PM
how can i convert strings into integers amahja56 C++ Programming 2 February 27th, 2004 06:27 PM





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