使用多个XSL文件转换XML [英] Transform XML with multiple XSL files

查看:82
本文介绍了使用多个XSL文件转换XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些XML,我想使用许多XSL文件转换为HTML。这些XSL文件都通过xsl:import和xsl:include语句相关,并且都是完成转换所需的。



我知道XSL有效,因为使用<?xml-stylesheet type =text / xslhref =transform.xsl?> 指令在浏览器打开的预先创建的XML文件中显示输出我想要。问题是我希望能够在动态生成的XML上复制这个功能。



有两种方法我可以看到这可以做到,但两者都有似乎有一些限制,我无法解决。



第一个解决方案是使用Javascript转换XML。据我所知,这将需要XSLTProcessor对象加载多个XSL文件,但Chrome(可能还有其他浏览器)不支持xsl:import非常好 - http://code.google.com/p/chromium/issues/detail?id=8441



我还考虑将XML写入iFrame或新窗口,但<?xml-stylesheet type =text / xslhref =transform。 xsl?> 指令在结果窗口中被注释掉。实际上写入新窗口的任何内容都是HTML - 我还没有找到将XML写入新窗口的方法。



那么如何才能显示一个浏览器窗口使用一组XSL文件转换的XML文件的结果?



更新



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



可能的解决方法:使用emscripten将xsltproc之类的工具编译成JavaScript。我实际上已经这样做了 - 请参阅 https://github.com/mcasperson/xsltproc.js



问题:firefox中的速度令人难以置信(Chrome浏览器需要5秒才能获得30+的火狐),而且你无法运行Chrome Web Worker中的代码 - https://code.google。 com / p / chromium / issues / detail?id = 252492



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



问题:直到浏览器开始实现 css attr(atrributename,url) )函数,没有办法将XML属性中的文件引用视为字符串以外的任何内容,这使得无法显示图像。



可能的解决方法:将所有XSL文件合并为单个样式sh eet



问题:这有点可能(参见合并多个xslt样式表),但xsl:import和xsl:include具有特定的语义,当简单地替换文件内容代替xsl:import或xsl时,这些语义不会传递:包括声明。对于分解为多个文件的大型XSL转换,此解决方案需要大量手动工作。



可能的解决方法:写出内容将XML转换为iframe或新窗口。



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



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



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

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



问题:这实际上可行(我没有试过它,但是Saxonica CE不是开源的(这是我们项目的要求)。

解决方案

如果你想要一个浏览器唯一的解决方案我会这样做:



静态xml



创建一个仅包含的简单静态xml对xsl的调用。这是在浏览器中打开的xml - 总是如此。这个xml文件可以包含控制流的属性设置,或者根本不包含任何内容。

 <?xml version = 1.0encoding =utf-8?> 
<?xml-stylesheet type =text / xslhref =cartoon2html.xsl?>
< xml />



动态普通xml



生成动态使用已定义的名称以您喜欢的方式使用XML - 在我的情况下是cartoons.xml。

 <?xml version =1.0编码= UTF-8 >?; 
< cartoons>
< cartoon name =Donald Duckpublisher =Walt Disney/>
< cartoon name =Mickey Mousepublisher =Walt Disney/>
< cartoon name =Batmanpublisher =DC Comics/>
< cartoon name =Supermanpublisher =DC Comics/>
< cartoon name =钢铁侠publisher =Marvel Comics/>
< cartoon name =蜘蛛侠publisher =Marvel Comics/>
< / cartoons>



带文档加载的XSLT



使用文档在xslt中贷款以引用生成的动态xml。通过在第一个apply-templates中使用select,所有其他模板都可以按预期工作。



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

 <?xml version =1.0encoding =UTF-8?> ; 
< xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transform>

< xsl:variable name =cartoonsselect =document('cartoons.xml')/ cartoons/>

< xsl:template match =/>
< html>
< head>
< title>漫画< / title>
< meta http-equiv =content-typecontent =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服务器提供文件才能执行转换。)


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 required to complete the transform.

I know the XSL works, because using the <?xml-stylesheet type="text/xsl" href="transform.xsl"?> directive in a pre-created XML file opened by the browser displays the output that I want. The problem is that I want to be able to replicate this functionality on dynamically generated XML.

There are two ways that I can see that this can possibly be done, but both seem to have limitations that I have not been able to work around.

The first solution is to use Javascript to transform the XML. From what I can tell, this will require the XSLTProcessor object to load multiple XSL files, but Chrome (and probably other browsers) don't support xsl:import very well - http://code.google.com/p/chromium/issues/detail?id=8441

I also looked at writing the XML to an iFrame or new window, but the <?xml-stylesheet type="text/xsl" href="transform.xsl"?> directives are commented out in the resulting window. Actually anything written into a new window is HTML anyway - I have not found a way to write XML into a new window.

So how can I get a browser window to display the result of an XML file transformed with a set of XSL files?

UPDATE

So here is the results of my research into this problem.

Possible workaround: compile a tool like xsltproc into JavaScript using emscripten. I have actually done this - see https://github.com/mcasperson/xsltproc.js

Problem: it is incredible slow in firefox (what takes 5 seconds in Chrome takes 30+ in firefox), and you can't run the code in a Chrome Web Worker - https://code.google.com/p/chromium/issues/detail?id=252492

Possible workaround: don't use XSL at all, but display the XML using CSS style sheets.

Problem: until browsers start implementing the css attr(atrributename, url) function, there is no way to treat a file reference in an XML attribute as anything other than a string, which makes it impossible to display images.

Possible workaround: Merge all the XSL files into a single style sheet

Problem: This is somewhat possible (see Merge multiple xslt stylesheets), but xsl:import and xsl:include have particular semantics that don't carry across when simply substituting a files contents in place of a xsl:import or xsl:include statement. For large XSL transforms broken up over multiple files, this solution would require a lot of manual work.

Possible workaround: Write out the contents of the XML into an iframe or new window.

Problem: It is not possible to write XML into a new window or iframe. The contents written into these elements is always assumed to be HTML, and inserted into a HTML->BODY element.

Possible workaround: Create a server side service that takes XML and then returns that XML with the XSL stylesheet directive. The service URL can then be used as a src attribute for an iframe or new window.

Problem: The service would have to be a GET end point, which means the XML to be returned would have to be included as a query parameter, which means you'll eventually run into issues with the length of the URL.

Possible workaround: Use a javascript XSL library like Saxonica CE.

Problem: This may actually work (I haven't tried it), but Saxonica CE is no open source (which is a requirement of our project).

解决方案

If you want a Browser only solution I would do it like this:

Static xml

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

Dynamic plain 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>

XSLT with document load

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).

这篇关于使用多个XSL文件转换XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆