Subject: Re: [xsl] xslt-events and questions From: Hermann Stamm-Wilbrandt <STAMMW@xxxxxxxxxx> Date: Wed, 11 Apr 2012 21:03:22 +0200 |
Hello, today I want to give an update * on the problems encountered while generating the HTML page from XSLT * demonstrate that dynamic XML really works by a rudimentary solitair0 demo Despite being able to pass "real" XML as argument to the 2nd argument XML string of function displayResult(...) in xslt-events.html below trying to do the same when creating that HTML page from XSLT fails: No '<' is allowed in the 2nd argument of displayResult(...) because that is part of an XSLT attribute! The solution is to pass the XML string serialized as 2nd argument, that works. Since even the initial position of solitair0 will be drawn by XSLT, the initial position HTML page is really minimal. The multiline string below is a Javascript string where '<' is fine, but '\' at line ends is needed. (clicking on the link will start "solitair0" demo in your browser) http://stamm-wilbrandt.de/en/xsl-list/solitair0/draw.html --------------------------------------------------------- <html> <!-- solitair0-demo: "initial position" draw.html --> <head> <script src="xslt-events.js" type="text/javascript"></script> </head> <body onload="javascript:displayResult('draw.xsl','\ <position> \ <row><f/><f/><f/><f/><f/><f/><f/><f/><f/></row> \ <row><f/><f/><f/><p/><p/><p/><f/><f/><f/></row> \ <row><f/><f/><f/><p/><p/><p/><f/><f/><f/></row> \ <row><f/><p/><p/><p/><p/><p/><p/><p/><f/></row> \ <row><f/><p/><p/><p/><h/><p/><p/><p/><f/></row> \ <row><f/><p/><p/><p/><p/><p/><p/><p/><f/></row> \ <row><f/><f/><f/><p/><p/><p/><f/><f/><f/></row> \ <row><f/><f/><f/><p/><p/><p/><f/><f/><f/></row> \ <row><f/><f/><f/><f/><f/><f/><f/><f/><f/></row> \ </position> \ ')"/> </html> And the only 116 lines of stylesheet do the display as well as a rudimentary mark action (click on any of the 33 fields, and it will be marked). You can repeat marking resulting in more and more entries getting marked. This is not a complete solitair yet, but just a proof that the concept really works and hopefully getting some comments on pitfalls, the attribute problem currently there or why only IE does not allow the marking click (the display is fine for all big5 browsers!). http://stamm-wilbrandt.de/en/xsl-list/solitair0/draw.xsl -------------------------------------------------------- <!-- solitair0-demo: draw.xsl based on xslt-events.js --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:output method="html"/> <!-- include "xslt-events.js" and draw outer border --> <xsl:template match="/"> <html> <head> <script src="xslt-events.js" type="text/javascript"></script> </head> <body><table border="1"><tr><td> <xsl:apply-templates select="position"/> </td></tr></table> </body></html> </xsl:template> <!-- draw board of fields without spacing --> <xsl:template match="position"> <table cellpadding="0" cellspacing="0"> <xsl:apply-templates select="row"/> </table> </xsl:template> <!-- row --> <xsl:template match="row"> <tr> <xsl:apply-templates select="*"> <xsl:with-param name="row" select="position()"/> </xsl:apply-templates> </tr> </xsl:template> <!-- field --> <xsl:template match="*"> <xsl:param name="row"/> <td> <xsl:variable name="xml"> <xsl:variable name="cur" select="."/> <xsl:apply-templates select="../.." mode="serialize-m"> <xsl:with-param name="cur" select="$cur"/> </xsl:apply-templates> </xsl:variable> <xsl:choose> <xsl:when test="not(starts-with(local-name(.),'f'))"> <a href="javascript:displayResult('draw.xsl','{$xml}')"> <xsl:call-template name="img"> <xsl:with-param name="col" select="substring('bw',1+((position()+$row) mod 2),1)"/> </xsl:call-template> </a> </xsl:when> <xsl:otherwise> <xsl:call-template name="img"> <xsl:with-param name="col" select="substring('bw',1+((position()+$row) mod 2),1)"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </td> </xsl:template> <!-- image based on figure name and field color $col --> <xsl:template name="img"> <xsl:param name="col"/> <xsl:element name="img"> <xsl:attribute name="style">display:block</xsl:attribute> <xsl:attribute name="border">0</xsl:attribute> <xsl:attribute name="src">gif/<xsl:value-of select="local-name(.)"/> <xsl:value-of select="$col"/>.gif</xsl:attribute> </xsl:element> </xsl:template> <!-- simple serializer including change of $cur to 'm' --> <xsl:template match="text()" mode="serialize-m"/> <xsl:template match="*" mode="serialize-m"> <xsl:param name="cur" select="/.."/> <xsl:variable name="new"> <xsl:choose> <xsl:when test="generate-id(.)=generate-id($cur)">m</xsl:when> <xsl:otherwise><xsl:value-of select="local-name()"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:text><</xsl:text> <xsl:value-of select="$new"/> <xsl:apply-templates select="@*" mode="serialize-m"/> <xsl:text>></xsl:text> <xsl:apply-templates mode="serialize-m"> <xsl:with-param name="cur" select="$cur"/> </xsl:apply-templates> <xsl:text></</xsl:text> <xsl:value-of select="$new"/> <xsl:text>></xsl:text> </xsl:template> <!-- no attributes yet ... --> <!-- <xsl:template match="@*" mode="serialize-m"> <xsl:value-of select="local-name()"/>= '<xsl:value-of select="string()"/>' </xsl:template> --> </xsl:stylesheet> Mit besten Gruessen / Best wishes, Hermann Stamm-Wilbrandt Level 3 support for XML Compiler team and Fixpack team lead WebSphere DataPower SOA Appliances https://www.ibm.com/developerworks/mydeveloperworks/blogs/HermannSW/ ---------------------------------------------------------------------- IBM Deutschland Research & Development GmbH Vorsitzende des Aufsichtsrats: Martina Koederitz Geschaeftsfuehrung: Dirk Wittkopp Sitz der Gesellschaft: Boeblingen Registergericht: Amtsgericht Stuttgart, HRB 243294 From: Hermann Stamm-Wilbrandt/Germany/IBM@IBMDE To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx, Date: 04/10/2012 06:28 PM Subject: [xsl] xslt-events and questions Hello, I know of Michael's talk on "XSLT in the browser (XMLPrague 2011)": http://www.youtube.com/watch?v=_eA6Br1qPA8 Saxon CE provides some features allowing to do XSLT processing based on user events and even allows running XSLT 2.0 on mobile devices. I just want to do XSLT processing in the browser with events (like "onLoad" or just '<a href="...">...</a>') and can live with a solution working fine on the big5 browsers (Chrome, Firefox, Internet Explorer, Opera, Safari). I need a solution providing the XML to be transformed dynamically. Why do I need that and cannot live with xml-stylesheet PI in stored XML files? For example I do want to do a game of (Peg) solitair in the browser by XSLT: http://en.wikipedia.org/wiki/Peg_solitaire Generating initial position from an XML configuration file is not difficult (see http://stamm-wilbrandt.de/en/xsl-list/solitair0/img0.gif). Now selecting a piece to move would mark that piece in a different color, eg. http://stamm-wilbrandt.de/en/xsl-list/solitair0/img1.gif . Then clicking on an empty field to complete the move would result in http://stamm-wilbrandt.de/en/xsl-list/solitair0/img2.gif . A standard XML file approach with xml-stylesheet runs into this problem: Even not taking the marking color into account we have 33 fields, and each of those can have a peg on it or not resulting in 2^33 or more than 8 billion possible configurations. I do not have that much webspace on my private web server ... ;-) So my idea is to have a link associated with a click for each possible field. The stylesheet will * take the XML configuration to display * generate HTML page in the browser * display the board as defined by the configuration XML * provide hyperlinks for each field * those hyperlinks generate dynamic XML based on the associated field * when clicking on a field, the dynamic XML will be transformed for new display First I thought on a form-post or XMLHttpRequest approach. But for those solutions a "backend service" is needed to just return the XML hidden in the sent data which seems to be ugly. Because the standard xml-stylesheet approach was not possible by argument from above I remembered the Javascript snippets I used in "[xsl] support of stylesheet embedding for ALL browsers" posting: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/201002/msg00301.html Basically these were: // "DOMParser.parseFromString() in Explorer" // http://www.van-steenbeek.net/?q=explorer_domparser_parsefromstring // "Transforming XML to XHTML in the Browser" // http://www.w3schools.com/xsl/xsl_client.asp function loadXMLDoc(dname) // "Transforming XML to XHTML in the Browser" (modified) // http://www.w3schools.com/xsl/xsl_client.asp function displayResult(xslURL, xmlStr) So just for demoing the (new?) approach (xslt-events) I use simple stylesheet "squares.ext.xsl" to generate a list of square values for the input values: Input "<ns> <n>2</n> <n>3</n> </ns>" will be transformed to output "2<sup>2</sup>=4<br>3<sup>2</sup>=9<br>". You can find the demo here: http://stamm-wilbrandt.de/en/xsl-list/solitair0/xslt-events.html Clicking on "doit1" link will execute squares.ext.xsl for 6 and 5, clicking on "doit2" will do the same for 2, 3 and 4. I tested this approach successfully with all big5 browsers. I know that I have to rely on the Javascript XSLT engines, not the browser's. I have some questions wrt the xslt-events.* files and links below: 1) Can you think of another approach without the need of a "backend service"? 2) Is there something which can be done to avoid the need to generate " in doit2 sample below (because " and ' are already used by the Javascript function call in the href)? 3) In DataPower XSLT Processor we have a proprietary extension element dp:url-open which allows tho post XML data like this: <dp:url-open target="someURL" response="someType"> <!-- XML data here will be posted to "someURL" --> </dp:url-open> How close can we come to this with xslt-events Javascript approach of <a href="javascript:displayResult(xslURL, xmlString)">...</a> ? This is http://stamm-wilbrandt.de/en/xsl-list/solitair0/xslt-events.html: ------------------------------------------------------------------------- <!-- xslt-events.html (4/10/2012) --> <html> <head> <script src="xslt-events.js" type="text/javascript"></script> </head> <body> <ul> <li/><a href="javascript:displayResult('squares.ext.xsl',' <ns><n>6</n><n>5</n></ns> ')">doit1</a> <li/><a href="javascript:displayResult('squares.ext.xsl',' <ns test="abc"><n>2</n><n>3</n><n>4</n></ns> ')">doit2</a> </ul> </body> </html> This is http://stamm-wilbrandt.de/en/xsl-list/solitair0/xslt-events.js: ----------------------------------------------------------------------- // xslt-events.js (4/10/2012) // "DOMParser.parseFromString() in Explorer" // http://www.van-steenbeek.net/?q=explorer_domparser_parsefromstring if(typeof(DOMParser) == 'undefined') { DOMParser = function() {} DOMParser.prototype.parseFromString = function(str, contentType) { if(typeof(ActiveXObject) != 'undefined') { var xmldata = new ActiveXObject('MSXML.DomDocument'); xmldata.async = false; xmldata.loadXML(str); return xmldata; } else if(typeof(XMLHttpRequest) != 'undefined') { var xmldata = new XMLHttpRequest; if(!contentType) { contentType = 'application/xml'; } xmldata.open('GET', 'data:' + contentType + ';charset=utf-8,' + encodeURIComponent(str), false); if(xmldata.overrideMimeType) { xmldata.overrideMimeType(contentType); } xmldata.send(null); return xmldata.responseXML; } } } // "Transforming XML to XHTML in the Browser" // http://www.w3schools.com/xsl/xsl_client.asp function loadXMLDoc(dname) { if (window.XMLHttpRequest) { xhttp=new XMLHttpRequest(); } else { xhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xhttp.open("GET",dname,false); xhttp.send(""); return xhttp.responseXML; } // "Transforming XML to XHTML in the Browser" (modified) // http://www.w3schools.com/xsl/xsl_client.asp function displayResult(xslURL, xmlStr) { // get parser var parser = new DOMParser(); xml = parser.parseFromString(xmlStr, "text/xml"); xsl = loadXMLDoc(xslURL); with (document) {open(); write("<div id='example'/>"); close(); } // code for IE if (window.ActiveXObject) { result=xml.transformNode(xsl); // display result document.getElementById("example").innerHTML=result; } // code for Mozilla, Firefox, Opera, etc. else if (document.implementation) { xsltproc = new XSLTProcessor(); xsltproc.importStylesheet(xsl); result = xsltproc.transformToFragment(xml, document); document.getElementById("example").appendChild(result); } } Mit besten Gruessen / Best wishes, Hermann Stamm-Wilbrandt Level 3 support for XML Compiler team and Fixpack team lead WebSphere DataPower SOA Appliances https://www.ibm.com/developerworks/mydeveloperworks/blogs/HermannSW/ ---------------------------------------------------------------------- IBM Deutschland Research & Development GmbH Vorsitzende des Aufsichtsrats: Martina Koederitz Geschaeftsfuehrung: Dirk Wittkopp Sitz der Gesellschaft: Boeblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] xslt-events and questions, Hermann Stamm-Wilbra | Thread | Re: [xsl] xslt-events and questions, Hermann Stamm-Wilbra |
Re: [xsl] Calling a template before, Peter Desjardins | Date | [xsl] Unravelling Imports, ihe onwuka |
Month |