Home & blog  /  Tag: XML  /

XMLPlayground.com - my new project

posted: 06 Jun '12 18:46 tags: XML, XSL, XQuery, DTD, Schema

So I finally got this off the ground. Months in the making, this is a sandbox environment for XML development, including (E)XSLT, XQuery (to a point), DTD, Schema and more.

It's sort of a JS Fiddle for XML. Sessions can be saved, resumed and shared. Output is generated and optionally styled with CSS.

I built it primarily because in my current job I'm working a lot with XSLT (1.0 - the horror) and found I could do with a test environment.

To that end it's probably XSL it's best suited to. XSL includes are supported and parameters can be passed into it. Your generated output can also pass parameters back into your XSL, allowing your output to be dynamic and responsive.

The downside is it's built in PHP, which is never the best choice for XML technologies.

For a start there's no XSL 2.0, nor any support for XQuery. The latter is mitigated to a point by the use of XQIB (XQuery in the Browser).

Here's a demo session showing how XML, XSL and CSS combine to make a sortable table of Soviet composers.

post a comment

Presenting XMLTree v.2.0

posted: 09 Feb '12 18:51 tags: XML, tree, traversal, node, JSONP, web service

You may remember XMLTree, which I launched several months ago. In short, it's a plugin that generates a tree from XML data, allowing you to traverse and interrogate the data but also bind events to the various branches of the tree.

Version 2.0 is now here, and comes with a host of powerful new features, including:

Sub-trees: loading data from a web service

Sub-trees allow you to load data branch-by-branch rather than all at once. This means you can use XMLTree with a web service, which serves up the root-level data on load, and then branch-specific data as and when branches are expanded.

Imagine you have a tree showing the boroughs of London. When a branch is expanded, it should show all the bus numbers that serve that borough.

Let's assume the web service returns the following XML format for the root data:

1

2     '1'>Wandsworth

3     '2'>Hackney

4     '3'>Croydon

5    

6

Knowing that, here's our tree instantiation:

1var ws_url = 'my_web_service.php';

2new XMLTree({

3     fpath: ws_url,

4     container: '#tree',

5     attrsAsData: 'borough_id',

6     subTreeBranches: true,

7     subTreeRequest: function(li) {

8         return ws_url+'?borough_id='+li.data('borough_id');

9     }

10});

By using the attrsAsData param (see below), we ensure that any borough_id attributes from the XML are transfered over as element data onto the tree LIs.

That's critical, because it means that, when a branch is expanded, we can look up that piece of data to determine URL of the web service for loading the next set of data.

The URL is determined and returned by the subTreeRequest param, a callback function that fires when a sub-tree-able branch is expanded and to which the expanded branch's LI is automatically passed. So the URL returned will be something like my_web_service.php?borough_id=13

In summary: to start with, only the root-level data is loaded. The data that goes within branches is determined only when a branch is expanded, by making a separate call to the web service. Crucial information is passed to the web service so it knows what data is returned - in this case, the ID of the clicked branch.

Transfer XML attributes to classes/element data

Attributes in your XML can now be transfered over to the resultant mark-up - in the form of either classes or element data attributes on the branch LIs.

In either case, you can either specify that all attributes should be transferred over, or just some.

Other features

Other, more minor features in this release include:

- support for loading XML over JSONP internet requests

- ability to auto-open the tree at a specific point once it's loaded

- ability to output, ignore or output but hide attributes as branches

Head over here to download, get usage info or view a demo.

post a comment

Additions to XML tree; jQuery XML parsing

posted: 24 Nov '11 08:45 tags: XML, tree, traversal, node, parsing

You may have seen my XMLTree plugin, posted a few weeks ago.

If you'll excuse the trumpet-blowing I do find this plugin among my most useful; I'm working on a number of projects right now that involve XML in the browser, and the ability to visualise it in a traversable tree is quiet satisfying.

New features (all documented on the script page) include:

- callback on resultant HTML - you can now specify a callback function which will be invoked after the tree has been generated. It is automatically passed a DOM reference to the tree ul so you can act on it.

- attributes - can now be ignored, hidden or shown. Hiding them is useful if you plan to traverse or interrogate the tree based on their existence or value, without wanting to show them to the user.

Bug fixes

This was an interesting one. With XMLTree you can either point it at an XML file for it to load, or manually pass it a well-formed string of XML.

In the latter case, it exploits a well-known (yet somewhat abused) perk of jQuery - that you can pass it a DOM or XML string and it will turn it into a nodeset.

But because this is intended for DOM creation, not XML creation, it assumes you're parsing an HTML document, not XML. The problem? If your XML contains any tags that share their names with any self-closing HTML tags, jQuery renders your XML invalid.

Consider the following example:

1var xml = "http://mitya.co.uklink>";

2console.log($(xml).html());

The output of that will be:

/>http://mitya.co.uk

...which is obviously not what you'd wanted.

As a fix for this XMLTree now renames (secretly) all of the node names - but restores their original names on output.

Ideally, of course, I wouldn't be lazy and rely on jQuery to parse XML - there are native ways (albeit different ones for different browsers). But for now this fix works just fine.

Head over here to download, get usage info or view a demo.

post a comment

Annoyances with client-side XSL transformation

posted: 25 Oct '11 19:37 tags: XML, XSL, webkit, import, browser, Opera

A current project of mine heavily involves XSL.

XSL is that rare thing: a technology that can run both on the client and on the server.This might be exciting if it wasn't so dubious; the likelihood of browsers and servers implementing a recommendation in equivalent fashion, just seems so unlikely.

That said, XSL does, I must admit, enjoy a pretty decent implementation in the browser, and with few cross-browser issues, too.

Naturally you won't want to be trying it in the likes of IE6 (which runs a very, very stripped-down version of XSL) but if you don't care about IE6, you should be fine.

Today, though, I did hit a snag: where XSL imports are concerned. Specifically, they don't work in Webkit browsers (Safari, Chrome).

This is only a problem when transforming your XSL through Javascript, i.e. within a webpage context - not if you're opening up the XML manually. In the latter case, your imports will work fine.

This is annoying, and it's not at all clear why Google/Apple don't add support for this.

Weirdness in Opera

As anyone close to me will tell you (or, rather, sigh and then tell you), my browser of choice is Opera. Now Opera does support XSL includes in the context of JS transformation... in a way.

If you load the XSL from a file, any XSL include statements within it will work.

1//utility function to load XML file and return as XML object

2function loadXMLDoc(dname) {

3     if (window.XMLHttpRequest)

4         xhttp=new XMLHttpRequest();

5     else

6         xhttp=new ActiveXObject("Microsoft.XMLHTTP");

7     xhttp.open("GET",dname,false);

8     xhttp.send("");

9     return xhttp.responseXML;

10}

11    

12//load and parse XML & XSL files

13var xml = loadXMLDoc('some_xml_file.xml');

14var xsl = loadXMLDoc('some_xsl_file.xsl');

15    

16//non-IE

17if (document.implementation && document.implementation.createDocument) {

18     xsltProcessor=new XSLTProcessor();

19     xsltProcessor.importStylesheet(xsl);

20     var output = xsltProcessor.transformToFragment(xml, document);

21//IE

22} else if (window.ActiveXObject)

23     var output = xml.transformNode(xsl);

24return output;

If, however, you specify and convert your XSL from a string, not from a file, you can forget about XSL includes.

1//prepare XML & XSL strings then parse into XML objects

2var xml = "1.0" encoding="ISO-8859-1"?>";

3var xsl = "1.0" encoding="ISO-8859-1"?>1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">xsl:template>";

4xml = $.parseXML(xml);

5xsl = $.parseXML(xsl);

This would appear to be a bug. In both cases, the resultant xml and xsl vars are both typeof == 'XML Document Object'. In other words, they should be equivalent - but only the former approach allows XSL includes.

Looks like I'll be doing my XSL on the server after all.

post a comment