Re: [xsl] Using JavaScript to access <xml:list> items

Subject: Re: [xsl] Using JavaScript to access <xml:list> items
From: "Charles Knell" <cknell@xxxxxxxxxx>
Date: Wed, 17 Jul 2002 09:43:28 -0700
I knew as soon I as I saw the word "JavaScript" in the subject, that
the first (correct) response that Hugh would be given would be along
the lines that Agnes suggested. To wear an old programming cliche just
a little bit thinner, "Just because JavaScript is a great hammer, you
shouldn't necessarily use it to drive a programming screw."

I have some info to offer on using JavaScript with MSXML, but first,
on the matter of hammers and screws; ditto on the namespace issue, but
here's a simpler XSLT to do what you were asking for.:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output method="html" indent="yes" encoding="UTF-8" />
  <xsl:param name="target" select="3" />
  <xsl:template match="List">
    <xsl:choose>
      <xsl:when test="contains(text(),$target)">
        <br />Match!!!<br />
      </xsl:when>
      <xsl:otherwise>
        <br />No match<br />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="/">
    <xsl:apply-templates>
      <xsl:with-param name="target" />
    </xsl:apply-templates>
  </xsl:template>
</xsl:stylesheet>

Sometimes (but really far less often than I originally thought) you will
need to use the procedural hammer of JavaScript. To do so, open your
stylesheet like this:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
  version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:ck="http://KiloNovember.com/XSLTExtensionFunctions";>
<msxsl:script language="JScript" implements-prefix="ck">
	<![CDATA[
            function filterXML(....
         ]]>
</msxsl:script>
<xsl:template match="/">
    ....
    <xsl:for-each select="ck:filterXML(....">
      ....
    </xsl:for-each>
</xsl:template>

1) Note the declaration of the msxsl namespace in the stylesheet element
and its use in the opening script element. Of course, it doesn't have
to be "msxsl" but you do need to declare and use a namespace to point
to the associated URI.

2) Note also in the stylesheet element the declaration of the "ck" namespace.
The content of the URI is irrelevant so long as it is a legal string,
and the namespace name is purely arbitrary. So long as it doesn't conflict
with other namespace declarations in the document, it doesn't matter
what you call it.

3) Note that when I call the funtion, I prefix the function name with
the namespace so as to create a qualified name (QName in XSL argot).

I may very well have overlooked something, and if I have I hope the other
readers will correct me, but I think this should be enough to get you
on the path.

MOST IMPORTANT: Think declaratively first, and only fall back on the
procedural as a last resort.
-- 
Charles Knell
cknell@xxxxxxxxxx - email


---- "Agnes Kielen" <a.kielen@xxxxxxx> wrote:
> Hi Hugh,
> 
> > I have an XML file:
> >
> > <?xml version="1.0"?>
> > <?xml-stylesheet type="text/xsl" href="ScriptTestQuest.xsl"?> <Root>
> > <Lists> <List>1 3 4</List> <List>1 4 5</List> <List>5 3 1</List>
> > </Lists> </Root>
> >
> > Which I am trying to transform with the xslt file:
> >
> > <?xml version="1.0"?>
> > <xsl:stylesheet version="1.0"
> >                 xmlns:xsl="http://www.w3.org/TR/WD-xsl"; > <xsl:script
> > language="javascript"> <![CDATA[ function car (e) {
> >    var strs = e.text.split(" ");
> >    return parseInt(strs[0]);
> > }
> 
> You are using an obsolute namespace only used by Microsoft.
> The official one is <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
> 
> See: http://www.netcrucible.com/ for more info.
> 
> In the namespace above  <xsl:eval> does not exist in stead you can
> use
> something like:
> 
> <msxml:script  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
> language="JScript">
>     <!-- your script -->
> </msxml:script>
> 
> But what result do you want because I get the feeling you don't need
> JavaScript at all.
> I you want to split the numbers this can be done with XSLT alone.
> With this XML.
> <Lists>
>  <List>1 3 4</List>
>  <List>1 4 5</List>
>  <List>5 3 1</List>
> </Lists>
> 
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> <xsl:output method="xml"/>
> <xsl:template match="/Lists">
>  <nums><xsl:apply-templates/></nums>
> </xsl:template>
> 
> <xsl:template match="List">
>  <xsl:call-template name="Split">
>   <xsl:with-param name="strInput" select="."/>
>  </xsl:call-template>
> 
> </xsl:template>
> 
> <xsl:template name="Split">
>  <!--This template will recursively break apart a comma-delimited string
> into child elements-->
>  <xsl:param name="strInput"/>
>  <xsl:param name="strDelimiter" select="' '"/>
>  <xsl:variable name="strNextItem" select="substring-before($strInput,
> $strDelimiter)"/>
>  <xsl:variable name="strOutput" select="substring-after($strInput,
> $strDelimiter)"/>
>  <xsl:variable name="strLen" select="string-length($strNextItem)"/>
>  <xsl:choose>
>   <xsl:when test="contains($strInput,$strDelimiter)">
>   <num>
>    <xsl:value-of select="$strNextItem"/>
>   </num>
>   <!-- At this point, the template will recursively call itself until
> the
> last comma is found -->
>   <xsl:call-template name="Split">
>    <xsl:with-param name="strInput" select="$strOutput"/>
>    <xsl:with-param name="strDelimiter" select="$strDelimiter"/>
>   </xsl:call-template>
>   </xsl:when>
>   <xsl:otherwise>
>    <!-- The otherwise clause will be reached when a comma is not located
> using contains() -->
>    <num>
>     <xsl:value-of select="$strInput"/>
>    </num>
>   </xsl:otherwise>
>  </xsl:choose>
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> I admit not the most easy XSLT but that the same is true for your
> javascript.
> 
> Cheers,
> Agnes
> 
> 
> 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
>  

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


Current Thread