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 September 7th, 2006, 02:16 AM
Registered User
 
Join Date: Sep 2006
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default using Javascritp with XSLT

Hello,

I have a XML file with following schema.

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="people.xsl"?>
<PEOPLE>
  <PERSON>
     <NAME>Mark Wilson</NAME>
     <ADDRESS>Australia</ADDRESS>
     <TEL>12345</TEL>
     <FAX>12345</FAX>
     <EMAIL>[email protected]</EMAIL>
  </PERSON>
  <PERSON>
      .....
  </PERSON>
</PROPLE


AND BELOW GOES MY people.xsl file. What I am trying to achieve here is first only the names will be displayed in a combobox and on selecting the name its details are displayed. how do i go about it?


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <head>
                    <title>People XML File</title>
                    <link rel="stylesheet" href="myStyle.css" />
                    <h2>My Address Book</h2>

                    <script language="Javascript" type="text/javascript">
                        function ChangeData(id)
                        {
                            var w = document.getElementById(id).selectedIndex;
                            var name = document.getElementById(id).options[w].value;
                            alert(name);
                            <xsl:variable name="name">
                                <xsl:attribute name="select">name</xsl:attribute>
                            </xsl:variable>

                            <xsl:if test="PEOPLE/PERSON/NAME=$name">
                                document.write('<br>EMail-Address : <xsl:value-of select="EMAIL"/></br>');
                            </xsl:if>
                        }
                    </script>
                </head>

                <select class="fontStyle" id="names" onchange="ChangeData('names')">
                        <xsl:for-each select="PEOPLE/PERSON">
                                <option>
                                    <xsl:attribute name="value">

                                        <xsl:value-of select="NAME"/>

                                    </xsl:attribute>

                                                <xsl:value-of select="NAME"/>

                                </option>
                        </xsl:for-each>
                </select>

            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>


Regards,
Mahboob

 
Old September 7th, 2006, 02:23 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I'm no expert on interactive Javascript programming, but you've basically got two design options. You can run a single XSLT transformation that creates a single HTML page with everything in it, but some of the data marked as hidden; when your Javascript is triggered by the user it can "unhide" the data. Or, you can put Javascript in the generated HTML page that, when activated, fires off a second XSLT transformation to produce new content in the page. Of course AJAX opens up new possibilities as well but I'm quite out of my depth on that.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old September 7th, 2006, 03:01 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

You seem to confuse what code is being run when. The first step with this sort of problem is to define your required output. When that is working then proceed to create the XSLT. The following transform gives a working page:
Code:
<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <html>
      <head>
        <title>People</title>
        <script type="text/javascript">
          var arrPeople = new Array();

          function Person(name, address, tel, fax, email)
          {
            this.name = name;
            this.address = address;
            this.tel = tel;
            this.fax = fax;
            this.email = email;
          }

          function createDataArray()
          {
            <xsl:apply-templates select="PEOPLE/PERSON" mode="createArray"/>
          }

          function showData(index)
          {
          var oPerson = arrPeople[index];
          var oDataRow = document.getElementById("rowDetails");
          oDataRow.cells[0].innerText = oPerson.name;
          oDataRow.cells[1].innerText = oPerson.address;
          oDataRow.cells[2].innerText = oPerson.tel;
          oDataRow.cells[3].innerText = oPerson.fax;
          oDataRow.cells[4].innerText = oPerson.email;
          }

          function init()
          {
            createDataArray();
            showData(0);
          }
        </script>
      </head>
      <body onload="init();">
        <div>
          <select onchange="showData(this.options[this.selectedIndex].value);">
            <xsl:apply-templates select="PEOPLE/PERSON" mode="addOptions"/>
          </select>
          <br/>
          <table>
            <caption>Details</caption>
            <thead>
              <tr>
              <th>Name</th>
              <th>Address</th>
              <th>Tel</th>
              <th>Fax</th>
              <th>Email</th></tr>
            </thead>
            <tbody>
              <tr id="rowDetails">
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
              </tr>
            </tbody>
          </table>
        </div>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="PERSON" mode="createArray">
    var oPerson = new Person("<xsl:value-of select="NAME"/>",
                             "<xsl:value-of select="ADDRESS"/>",
                             "<xsl:value-of select="TEL"/>",
                             "<xsl:value-of select="FAX"/>",
                             "<xsl:value-of select="EMAIL"/>");
    arrPeople.push(oPerson);<xsl:text>#x0a;</xsl:text><xsl:text>#x0d;</xsl:text>
  </xsl:template>

  <xsl:template match="PERSON" mode="addOptions">
    <option value="{position() - 1}">
      <xsl:if test="position() = 1">
        <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      <xsl:value-of select="NAME"/>
    </option>
  </xsl:template>

</xsl:stylesheet>
--

Joe (Microsoft MVP - XML)
 
Old September 7th, 2006, 03:20 AM
Friend of Wrox
 
Join Date: May 2005
Posts: 140
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I have never embedded the Javascript into an XSL. You can design an AJAX (JavaScript with Async. XML) application which gets the XML und XSL via DOM and you can also do this scripting seperately. A Brief coding for you

function loadXMLDoc(xmlDocURL) {
    srcTree = new ActiveXObject("Msxml2.DOMDocument.3.0");
    srcTree.async = false;
    if (srcTree.load(xmlDocURL))
        return srcTree;
    else
        return false ;
}

function loadXSLDoc(xslDocURL) {
    xsltTree = new ActiveXObject("Msxml2.XSLTemplate.3.0");
    xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0" );
    xslDoc.async = false;
    if (!xslDoc.load(xslDocURL))
        return false ;
    xsltTree.stylesheet = xslDoc;
    return xslDoc;
}

function generateHTML(xmlTree,xslTree) {
    xslProc = xsltTree.createProcessor();
    xslProc.addParameter("day",epoWeatherDay);
    xslProc.addParameter("wmo", epoWeatherWMO);
    xslProc.input = xmlTree;
    xslProc.transform();
    html = xslProc.output;
    return html;
}

function initWeather() {
    // Initialisation
    html = "" ;
    xmlPath= "http://kunden.wetteronline.de/cgi-bin/epo/epo?OPT=vhs&WMO=" + epoWeatherWMO + "&PARTNER=e28p03o06&LANG=en";
    weatherLayer = document.getElementById(epoWeatherElementId) ;
    if (!weatherLayer)
        return ;

    // Processing
    weatherLayer.innerHTML = "Loading data, please wait ..." ;
    xmlTree = loadXMLDoc(xmlPath);
    xslTree = loadXSLDoc(xslPath);
    if (!xmlTree)
        html += "<br/>- Cannot load weather data !" ;
    if (!xslTree)
        html += "<br />- Cannot load weather stylesheet !" ;
    if (html == "")
        html = generateHTML(xmlTree, xslTree);
    else
        html = "<p>Warning:" + html + "</p>" ;
    weatherLayer.innerHTML = html;
}

Your attitude determines your altitude
 
Old September 7th, 2006, 03:46 AM
Registered User
 
Join Date: Sep 2006
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks joe It worked :) ...but I had to remove the line
<xsl:text>#x0a;</xsl:text><xsl:text>#x0d;</xsl:text> as this line was throwing error.

I have one doubt about how its working...

The function createDataArray() which is first called at the body init, will it actually go and call

<xsl:template match="PERSON" mode="createArray">
    var oPerson = new Person("<xsl:value-of select="NAME"/>","<xsl:value-of select="ADDRESS"/>","<xsl:value-of select="TEL"/>", "<xsl:value-of select="FAX"/>",
                             "<xsl:value-of select="EMAIL"/>");
                            arrPeople.push(oPerson);
  </xsl:template>


Can you please explain me the functionality of "mode" in <xsl:apply-templates select="PEOPLE/PERSON" mode="createArray"/>

Regards,
Mahboob

 
Old September 7th, 2006, 04:06 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Can you please explain me the functionality of "mode" in <xsl:apply-templates select="PEOPLE/PERSON" mode="createArray"/>


Yes, it's explained in the spec:

http://www.w3.org/TR/xslt#modes

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old September 7th, 2006, 04:31 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

The steps are:
 
  • The XSLT runs and produces all the HTMl and script.
  • The HTML and script is interpreted by the browser.


You need to examine the raw source code after the transform to appreciate the HTML, you'll see that there's no trace left of the original XML as such.
The
Code:
<xsl:template match="PERSON" mode="createArray">
just writes out some JavaScript that creates one Person instance for each <PERSON> in the XML file.

--

Joe (Microsoft MVP - XML)
 
Old September 7th, 2006, 04:33 AM
Registered User
 
Join Date: Sep 2006
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Michael. got it.
Thanks NEO1976.


 
Old September 7th, 2006, 04:48 AM
Registered User
 
Join Date: Sep 2006
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

thanks all of you.. you all been of great help.






Similar Threads
Thread Thread Starter Forum Replies Last Post
How to call DLL Method in Javascritp? URGENT!!!!!! prabhakar123 Javascript 26 November 28th, 2011 07:06 AM
how to forward some action from javascritp msg2ajay Javascript 1 September 3rd, 2007 09:08 AM
Can XSLT read DTD/schema and Generate XSLT.. ROCXY XSLT 1 November 6th, 2006 09:39 AM
dynamic xslt -> xslt creation namespace problem jkmyoung XSLT 2 July 15th, 2006 12:42 AM
Working with Forms and Popup window in Javascritp danieljava JSP Basics 0 November 20th, 2005 09:57 PM





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