我有一些XML,我想用一些XSL文件转换为HTML。 这些XSL文件通过XSL所有相关:import和xsl:include语句,并完成转换所需的所有。
我知道XSL的作品,因为使用<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
指令由浏览器中打开一个预先创建的XML文件显示了我想要的输出。 问题是,我希望能够在动态生成的XML复制此功能。
有两种方法,我可以看到,这都不可能做到,但两者似乎有一个,我一直没能解决的限制。
第一个方案是使用JavaScript来转换XML。 从我可以告诉,这将需要XSLTProcessor中对象加载多个XSL文件,但Chrome浏览器(可能其他浏览器)不支持XSL:进口很好- http://code.google.com/p/chromium/问题/细节?ID = 8441
我还研究了写入XML到的iFrame或新窗口,但<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
指令是在所得到的窗口注释。 其实写东西到一个新的窗口是HTML无论如何 - 我还没有找到一个方式来写XML到一个新窗口。
所以,我怎么能得到一个浏览器窗口中显示了一组XSL文件转换的XML文件的结果呢?
UPDATE
因此,这里是我的研究成果了这个问题。
可能的解决方法 :使用emscripten编译像xsltproc的工具转换为JavaScript。 其实我已经做到了这一点-看到https://github.com/mcasperson/xsltproc.js
问题 :它是在Firefox(什么需要5秒的Chrome 30+需要在Firefox)令人难以置信的速度慢,无法运行在Chrome Web工作的代码- https://code.google.com/p/chromium/问题/细节?ID = 252492
可能的解决方法 :在所有不使用XSL,但使用CSS样式表显示XML。
问题 :直到浏览器开始实施css attr(atrributename, url)
功能,有没有办法来治疗的XML属性作为不是一个字符串,这使得它无法显示图像的任何其他文件引用。
可能的解决方法 :合并所有XSL文件合并为一个样式表
问题 :这在某种程度上可能(见合并多个XSLT样式表 ),但XSL:import和xsl:包括具有不跨越携带时只需在一个地方的xsl代以文件的内容特定的语义:进口或XSL:include语句。 在过去的多个文件打散大XSL转换,该解决方案将需要大量的手工工作。
可能的解决方法 :写出XML的内容到iframe或新窗口。
问题 :这是不可能写XML到一个新窗口或iframe。 写入到这些元素的内容总是假设为HTML,并插入到HTML的“BODY元素。
可能的解决方法 :创建一个服务器端的服务,它的XML,然后返回与XSL样式表指令,XML。 然后,服务URL可以被用作一个src
为的iframe或新窗口属性。
问题 :服务必须是一个GET终点,这意味着要返回都必须包括一个查询参数,这意味着你最终会遇到问题与URL的长度的XML。
可能的解决方法 :使用JavaScript库的XSL像Saxonica CE 。
问题 :这实际上可能工作(我还没有尝试过),但Saxonica CE是不开源的(这是我们项目的要求)。
如果你想要一个浏览器唯一的解决办法,我会做这样的:
静态XML
使包含只调用了xsl一个简单的静态XML。 这是在浏览器中打开XML - 永远。 这个XML文件可能包含属性设置来控制流量或者什么都没有为这个例子。
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="cartoon2html.xsl"?>
<xml/>
动态纯XML
产生在使用定义的名称自己喜欢的方式动态XML - 在我的情况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>
XSLT处理文档负载
使用在XSLT文档贷款基准生成的动态XML。 通过在第一选择使用应用模板按计划所有其他模板会工作。
采取在顶部和在代码中的变量引用的进一步回落密切关注。 这是执行的魔力。
<?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>
你可以将这三个文件保存到选定的目录,并在Firefox打开静态XML文件。 (Chrome和Safari浏览器也许必须有文件通过Web服务器提供执行转换)。
我会建议使用jQuery导入和样式的XML。
像这样将允许您导入XML每当一个函数被调用(链接到一个按键或刷新按钮,甚至连计时器的功能。)
$.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');
}
}
})
而XML会是这个样子:
<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>
当然,而不是导入到一个div你可以导入XML到一个表或任何其他类型的HTML元素。
刚才我有同样的问题。 我的解决办法是传播包括直接进入XML。 这个代码是根据浏览器,Firefox和IE 10,9,8和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));
}
}
}
}