Javascript 使用多个XSL文件转换XML

Javascript 使用多个XSL文件转换XML,javascript,xml,xslt,Javascript,Xml,Xslt,我想用一些XSL文件将一些XML转换成HTML。这些XSL文件都通过XSL:import和XSL:include语句相互关联,并且都是完成转换所必需的 我知道XSL是有效的,因为在浏览器打开的预先创建的XML文件中使用指令可以显示我想要的输出。问题是我希望能够在动态生成的XML上复制此功能 有两种方法我可以看出这是可以做到的,但这两种方法似乎都有我无法克服的局限性 第一种解决方案是使用Javascript转换XML。据我所知,这需要XSLTProcessor对象加载多个XSL文件,但Chrome

我想用一些XSL文件将一些XML转换成HTML。这些XSL文件都通过XSL:import和XSL:include语句相互关联,并且都是完成转换所必需的

我知道XSL是有效的,因为在浏览器打开的预先创建的XML文件中使用
指令可以显示我想要的输出。问题是我希望能够在动态生成的XML上复制此功能

有两种方法我可以看出这是可以做到的,但这两种方法似乎都有我无法克服的局限性

第一种解决方案是使用Javascript转换XML。据我所知,这需要XSLTProcessor对象加载多个XSL文件,但Chrome(可能还有其他浏览器)不太支持XSL:import-

我还研究了将XML写入iFrame或新窗口,但是
指令在结果窗口中被注释掉。实际上,写入新窗口的任何内容都是HTML——我还没有找到一种将XML写入新窗口的方法

那么,如何让浏览器窗口显示用一组XSL文件转换的XML文件的结果呢

更新

这是我对这个问题的研究结果

可能的解决方法:使用emscripten将类似xsltproc的工具编译成JavaScript。我真的做到了——看到了吗

问题:在firefox中速度非常慢(在Chrome中需要5秒,在firefox中需要30秒以上),并且您无法在Chrome Web Worker中运行代码-

可能的解决方法:根本不使用XSL,而是使用CSS样式表显示XML

问题:在浏览器开始实现
css attr(atributename,url)
功能之前,无法将XML属性中的文件引用视为字符串以外的任何内容,这使得无法显示图像

可能的解决方法:将所有XSL文件合并到一个样式表中

问题:这在某种程度上是可能的(请参阅),但是xsl:import和xsl:include具有特定的语义,当简单地用文件内容代替xsl:import或xsl:include语句时,这些语义是无法实现的。对于拆分为多个文件的大型XSL转换,此解决方案需要大量手动工作

可能的解决方法:将XML内容写入iframe或新窗口

问题:无法将XML写入新窗口或iframe。写入这些元素的内容始终假定为HTML,并插入到HTML->BODY元素中

可能的解决方法:创建一个接受XML的服务器端服务,然后使用XSL样式表指令返回该XML。然后,服务URL可以用作iframe或新窗口的
src
属性

问题:服务必须是GET端点,这意味着要返回的XML必须作为查询参数包含在内,这意味着您最终会遇到URL长度问题

可能的解决方法:使用javascript XSL库,如


问题:这可能确实有效(我没有尝试过),但Saxonica CE不是开源的(这是我们项目的一个要求)。

我建议使用jquery导入XML并设置其样式

类似这样的东西将允许您在调用函数时导入XML(链接到按键、刷新按钮甚至计时器的函数)

$.ajax({
键入:“获取”,
url:“FILENAME.xml”,
数据类型:“xml”,
成功:函数(xml){
$(xml).find('site')。each(function(){//查找父节点
var id=$(this).attr('id');//父节点的id
var title=$(this).find('title').text();//在父节点中查找标题节点
var url=$(this).find('url').text();//在父节点中查找url节点
var description=$(this).find('descr').text();//等。。。
var img=$(this).find('img').text();//等等。。。
//创建具有父节点id的div(用于单个样式)
$('')
.addClass('添加一个div类')
//设置div的css
.css({set css})
//将此XML分配div的内部HTML设置为带有“description”和“img”的超链接“title”
.html(“”+说明+“”)
//将新创建的元素附加到主体
.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>

http://blah.com
imgs/image1.png
这是一个描述
标题
http://filler.com
imgs/image2.jpg
这是另一种描述
标题2

当然,您可以将XML导入表或任何其他类型的HTML元素,而不是导入到div中。

如果您想要只使用浏览器的解决方案,我会这样做:

<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>
静态xml 制作一个简单的静态xml,其中只包含对xsl的调用。这是在浏览器中打开的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中使用document loan引用生成的动态xml。通过在第一个apply模板中使用select,所有其他模板都将按预期工作

仔细查看代码顶部和更下方的变量引用。这就是执行魔术的地方

<?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>

卡通片