Re: [xsl] storing a variable value using <script> tags in between

Subject: Re: [xsl] storing a variable value using <script> tags in between
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 8 Jan 2001 09:58:02 +0000
Hi Rosa,

You've sent three messages recently that deal with roughly the same
area: trying to combine Javascript with XSLT.  To see what's going
wrong, we have to go back to basics.

The purpose of XSLT is to transform XML in one XML vocabulary to
another format, often XML in another vocabulary or HTML.  You have
your original data in some XML:

  <QuestionDefs>
    <QuestionDef Category="Travel"
                 Id="departure_date"
                 Caption="What is your departure date?"
                 Style="Date"
                 Required="Quote">
      <QuestionCheck Value=">Today"
                     Message="Return date must be after today" />
    </QuestionDef>
  </QuestionDefs>

You are transforming this data into HTML. The HTML that you produce is
then displayed in a browser. The browser understands how to display
HTML. It also understands how to run Javascript scripts. Once the
HTML is in the browser it is almost exactly as if you had written that
HTML by hand, in a separate file - the browser doesn't automatically
know that the information in the HTML file comes from XML originally,
or that XSLT was involved.

Similarly, the XSLT stylesheet could be producing anything - the XSLT
processor doesn't care that it's producing HTML.  It doesn't look at
what it's producing and think about how it's going to look on the
screen.  Similarly, it doesn't look inside SCRIPT elements it produces
and interpret the Javascript in them.  As far as the XSLT processor is
concerned, it is producing a SCRIPT element and then a load of text
within that SCRIPT element.

So, when you write:
  
  <xsl:variable name="qNum">
    <SCRIPT>
      parent.qNo;
    </SCRIPT>
  </xsl:variable>

You are creating a variable called $qNum that holds a result tree
fragment.  The result tree fragment consists of a root node, with a
SCRIPT element underneath it, with a text node underneath that.  The
XSLT processor doesn't evaluate things within a SCRIPT element.  As
far as it's concerned, it could be called WIBBLE and it would mean
exactly the same thing to the XSLT processor.

When you get the value of the $qNum variable, you're getting the
string value of the root node of the result tree fragment that you've
created.  This consists of all the text nodes within the result tree
fragment concatenated together, i.e. the string 'parent.qNo' with lots
of whitespace around it.  The string isn't interpreted in any special
way: it's just a string.  It could equally say 'Hello, world!' and it
would mean exactly the same thing to the XSLT processor.

I don't exactly know what you are trying to do here. What do you want
$qNum to be set to? If you want it to be set to the 'qNo' attribute of
the QuestionDef's parent QuestionDefs element, then you can use:

  <xsl:variable name="qNum" select="../@qNo" />

Your other question was about accessing values from the XML source in
order to evaluate values typed in by users:

> when I type in the date (onChange) I want the javascript to compare
> this value to the QuestionCheck's Value attribute, and then if
> that's true, I will show the message attribute.

Typing in a date is an activity that takes place within the browser.
The Javascript that deals with the onChange event has to be part of
that HTML document being shown by the browser. You want to have
Javascript in the HTML that goes something like:

  function getDate() {
    if (myForm.dDate >Today) {
      alert('Return date must be after today');
    }
  }

Parts of this bit of Javascript are from the XML source.  In
particular the '>Today' bit of the if test and the string value of the
alerted message come from the XML source.  When you create the HTML
page, you also create the Javascript that it contains.  You construct
the Javascript with XSLT in just the same way as you can construct a
paragraph with XSLT.  So, in the XSLT you can produce the above
Javascript based on the source XML with something like:

  function getDate() {
    if (myForm.dDate <xsl:value-of select="QuestionCheck/@Value" />) {
      alert('<xsl:value-of select="QuestionCheck/@Message" />');
    }
  }

When the XSLT processor runs over this stylesheet it will produce the
Javascript you have above.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread