Solved

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

Posted on 2003-11-07
7
646 Views
Last Modified: 2008-03-10
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>
0
Comment
Question by:lrr81765
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 6

Expert Comment

by:metalmickey
ID: 9702225
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
 
LVL 26

Expert Comment

by:rdcpro
ID: 9703079
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
 

Author Comment

by:lrr81765
ID: 9703770
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
Cloud Training Guides

FREE GUIDES: In-depth and hand-crafted Linux, AWS, OpenStack, DevOps, Azure, and Cloud training guides created by Linux Academy instructors and the community.

 
LVL 26

Expert Comment

by:rdcpro
ID: 9704104
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
 

Author Comment

by:lrr81765
ID: 9732774
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
 

Author Comment

by:lrr81765
ID: 9732873
Alas, reading the Magic Book tells me that the <xsl:variable> cannot be updated :(
0
 
LVL 26

Accepted Solution

by:
rdcpro earned 500 total points
ID: 9733344
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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

632 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question