Use Jscript function result in <xsl:if test=>

I am trying to use a <xsl:if> to test the value returned from a Jscript. I am using .Net Framework 1.1 to do transformation (XSLTransform). This works in MSXML4 ( using Xselerator ).  

The error  receive "Index is outside bounds of the array", is related to the <xsl:if>.

Here is sample code:
XML
-------------------------
<?xml version='1.0'?>
<root/>

XSL
---------------------------
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:user="urn:test">
      <msxsl:script language="JScript" implements-prefix="user" >
var CurrentLine = 1;

function GetAttr(s)
{
      return ' ';
}


function GetLine()  {
      return CurrentLine;
}
function IncrLine()  {
      CurrentLine = ++CurrentLine;
      return "";
}
      </msxsl:script>
      <xsl:template match="/">
            <test>
                  <line>
                        <xsl:value-of select="user:GetLine()" />
                  </line>
                  <line>
                        <xsl:if test="(user:GetLine() = 1)">
                              <sub>Passed</sub>
                        </xsl:if>
                  </line>
                  <line>
                        <xsl:value-of select="user:IncrLine()" />
                        <xsl:value-of select="user:GetLine()" />
                  </line>
            </test>
      </xsl:template>
</xsl:stylesheet>

////////////////////////////////////////////
Code
///////////////////////////////////////////
Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports System.Xml.Xsl

Public Class Sample

   Private Const filename As String = "rootr.xml"
   Private Const stylesheet As String = "calc.xsl"

   Public Shared Sub Main()

    'Create the XslTransform and load the stylesheet.
    Dim xslt As XslTransform = New XslTransform
    xslt.Load(stylesheet)

    'Load the XML data file.
    Dim doc As XPathDocument = New XPathDocument(filename)

    'Create an XmlTextWriter to output to the console.            
    Dim writer As XmlTextWriter = New XmlTextWriter(Console.Out)
    writer.Formatting = Formatting.Indented

    'Transform the file.
    xslt.Transform(doc, Nothing, writer, Nothing)
    writer.Close()
  End Sub
End Class
'''''''''''''''''''''''''''''''''''//////////////////////////////////

Expected Output:
--------------------------------------------------------
<?xml version="1.0" encoding="UTF-16"?>
<test xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:test">
      <line>1</line>
      <line>
            <sub>Passed</sub>
      </line>
      <line>2</line>
</test>
lrr81765Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

metalmickeyCommented:
I dont know anything about Jscript or .net  and i may be way off, but i think you have to screen javascript in the xslt as the parser will try to parse the characters in the javascript.

try encapsulating it in a CDATA tag

<![CDATA[

Your javascript goes here  

  ]]>


IE

<msxsl:script language="JScript" implements-prefix="user" >
<![CDATA[
var CurrentLine = 1;

function GetAttr(s)
{
    return ' ';
}


function GetLine()  {
    return CurrentLine;
}
function IncrLine()  {
    CurrentLine = ++CurrentLine;
    return "";
}
 ]]>
    </msxsl:script>

Should there be some XML in the XML file?

<?xml version='1.0'?>
<root/>



MM
0
rdcproCommented:
I hate to say this, but what lrr81765 is trying to do is a *bad* idea.  You should never code side-effects in XSLT.  Don't create a global variable and change it using functions calls, especially to get around the immutability of XSLT variables.  The reason for this is that you cannot predict the order of execution for templates.  The spec specifically states this, and the processor is free to make whatever optimizations it chooses.   I strongly suggest you come up with a different approach.

Regards,
Mike Sharp
0
lrr81765Author Commented:
Thank you all for the quick response. metalmickey, I have tried this as well, but it does not work.

rdcpro, what I am doing is keeping track of a line position ( not the same as currentline() or position() ). I have the pleasure of controlling the envioroment that it runs on (MS Framework) as well.  To envision this, imagine a parameter that is passed in called "lines" that is equal to 10. I want to continue processing until 10 lines have been processed, and perhaps, do something different on lines 2,3,6, and 9.

Can you give some type of alternative?
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

rdcproCommented:
Sure.  Use XSLT recursion.  I just posted a similar example.  This one looks to see the largest value of <event-week>, then builds the number of rows specified.  In this particular case, there is one node <event-week>6</event-week>, so it builds 6 rows on the table.  You can view it in action here:

http://dev.rdcpro.com/Members/rdcpro/misc/events.xml

The XSLT that makes this happen is:

http://dev.rdcpro.com/Members/rdcpro/misc/events-recursive.xslt

Or you can download them from:

http://dev.rdcpro.com/Members/rdcpro/misc/

Obviously, you could also set a parameter externally.

The thing about side effects in XSLT is that even within the MS .NET framework, you could find a subsequent version of the framework might make an optimization in the template processor that will break your code.   The specification is very specific on this point.  XSLT is Turing-complete, so there should never be a situation where you need a side-effect function like this.  

Regards,
Mike Sharp
0
lrr81765Author Commented:
rdcpro,
Ok I think I have a grip on the recursion.

Can I use the variable in the script functions (i.e.:
function GetLine()  {
      var x;
      x=<xsl:value-of select="$CurrentLine"/>;
      return x;
}

function IncrLine()  {
      <xsl:variable name="CurrentLine" select="$CurrentLine + 1" />;
      return ;
}

function ResetLine()  {
      <xsl:variable name="CurrentLine" value="1" />;
      return "";
}

-----------
And then do my test as <xsl:if test=$CurrentLine = 1" />

and be able to increment the variable with <xsl:value-of select="user:IncrLine()" />

?


0
lrr81765Author Commented:
Alas, reading the Magic Book tells me that the <xsl:variable> cannot be updated :(
0
rdcproCommented:
You're still trying to get around immutability.

The key to understanding it is that a variable or parameter cannot be updated *in the current instance of a template*.  So if you want a new value for a variable, you need a new template instance.  That's why you use XSLT recursion for this.

Here's a simple example of a recursive counter, that increments an xsl:variable using recursion.  Remember, if the variable counts to 10, there will be 10 instances of the template that contains the variable.  Whether you do the recursion test before or after  you output the variable will determine whether the counting is ascending or descending...examine this example:

http://dev.rdcpro.com/Members/rdcpro/snippets/recursionandcounting/

Regards,
Mike Sharp
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.