I have some XML that I\'d like to transform into HTML using a number of XSL files. These XSL files are all related through xsl:import and xsl:include statements, and all require
If you want a Browser only solution I would do it like this:
Make a simple static xml that contains only the call to the xsl. This is the xml that is opened in the browser - always. This xml file could contain property settings to control the flow or nothing at all as this example.
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="cartoon2html.xsl"?>
<xml/>
Generate the dynamic XML in your favourite way using a defined name - in my case cartoons.xml.
<?xml version="1.0" encoding="utf-8"?>
<cartoons>
<cartoon name="Donald Duck" publisher="Walt Disney" />
<cartoon name="Mickey Mouse" publisher="Walt Disney" />
<cartoon name="Batman" publisher="DC Comics" />
<cartoon name="Superman" publisher="DC Comics" />
<cartoon name="Iron Man" publisher="Marvel Comics" />
<cartoon name="Spider-Man" publisher="Marvel Comics" />
</cartoons>
Use document loan in the xslt to reference the generated dynamic xml. By using select in the first apply-templates all other templates will work as intended.
Take a close look at the variable reference at top and the further down in the code. This is where the magic is performed.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="cartoons" select="document('cartoons.xml')/cartoons" />
<xsl:template match="/">
<html>
<head>
<title>Cartoons</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<xsl:apply-templates select="$cartoons" />
</body>
</html>
</xsl:template>
<xsl:template match="cartoons">
<table>
<xsl:apply-templates />
</table>
</xsl:template>
<xsl:template match="cartoon">
<tr>
<td><xsl:value-of select="@name" /></td>
<td><xsl:value-of select="@publisher" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
You could save these three files into a directory of choice and open the static xml file in firefox. (Chrome and perhaps Safari has to have the file served through a web server to perform the transformation).
I would recommend using jquery to import and style the XML.
Something like this would allow you to import the XML whenever a function is called (a function linked to a keypress or a refresh button or even a timer.)
$.ajax({
type: "GET",
url: "FILENAME.xml",
dataType: "xml",
success: function(xml) {
$(xml).find('site').each(function(){ //finds parent node
var id = $(this).attr('id'); //id of parent node
var title= $(this).find('title').text(); //finds title node within parent node
var url = $(this).find('url').text(); //finds URL node within parent node
var description = $(this).find('descr').text(); //etc...
var img = $(this).find('img').text(); //etc...
// Creates div with id of parent node (for individual styling)
$('<div id="link_'+id+'">')
.addClass('add a div class')
//sets css of div
.css({set css})
// Sets the inner HTML of this XML allocated div to hyperlinked 'title' with 'description' and an 'img'
.html('<a href="'+url+'">'+title+'</a>'+description+'<img src="'+img+'">')
// Append the newly created element to body
.appendTo('#holder');
}
}
})
And the XML would look something like this:
<site id="0">
<url>http://blah.com</url>
<img>imgs/image1.png</img>
<description>this is a description</description>
<title>Title</title>
</site>
<site id="1">
<url>http://filler.com</url>
<img>imgs/image2.jpg</img>
<description>this is another description</description>
<title>Title 2</title>
</site>
Of course instead of importing to a div you could import the XML to a table or any other type of HTML element.
I had the same problem just now. My solution was to propagate the includes directly into the XML. This code was tested under Chrome, Firefox and IE 10,9,8 and 7.
function propegateIncludes(dname,xml, isExplorer) {
var preTag = isExplorer ? "xsl:" : "";
var TAG_STYLESHEET = preTag + "stylesheet", TAG_INCLUDE = preTag
+ "include", TAG_TEMPLATE = preTag + "template";
var stylesheets = xml.getElementsByTagName(TAG_STYLESHEET);
if (stylesheets.length == 0) {
return;
}
var includes = xml.getElementsByTagName(TAG_INCLUDE);
if (includes.length == 0) {
return;
}
var stylesheet = stylesheets[0];
var path = dname.substring(0, dname.lastIndexOf('/'));
for ( var i = 0; i < includes.length; i++) {
var args = includes[i].attributes;
var includeXml = null;
for ( var a = 0; a < args.length; a++) {
if (args[a].nodeName == "href") {
includeXml = loadXMLDoc(path + "/" + args[a].nodeValue);
break;
}
}
stylesheet.removeChild(includes[i]);
if (includeXml != null) {
var templates = includeXml.getElementsByTagName(TAG_TEMPLATE);
for (var t = 0; t < templates.length; ++t) {
stylesheet.appendChild(templates[t].cloneNode(true));
}
}
}
}