如何在Chrome中使用变量执行XSLT转换

时间:2018-11-17 12:21:55

标签: javascript xml xslt

我正在尝试进行XSL转换。

但是,每当引用带有文档片段的变量时,转换似乎都会失败。

我创建了一个JSFiddle来演示此问题。示例中的XML是允许XSLT运行的虚拟文档。

我在做什么错了?

Javascript:

var xml = [
    '<p xmlns="http://www.w3.org/1999/xhtml">',
    '<\/p>'
    ].join('\n');

var xsl = [
    '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">',
    '<xsl:variable name="xmlVar">',
    '<aaaa value="It works"\/>',
    '<\/xsl:variable>',
    '<xsl:template match="\/">',
    '<ROOT>',
    //works ok after commenting out
    '<xsl:value-of select="$xmlVar\/aaaa\/@value"\/>',
    '<\/ROOT>',
    '<\/xsl:template>',
    '<\/xsl:stylesheet>'
    ].join('\n');



var domParser = new DOMParser();

var xmlDoc = domParser.parseFromString(xml, 'application/xml');

var xslDoc = domParser.parseFromString(xsl, 'application/xml');

var xsltProc = new XSLTProcessor();
xsltProc.importStylesheet(xslDoc);
try{
var result = xsltProc.transformToFragment(xmlDoc, document);
} catch(exc) {
document.getElementById('error').innerHTML = exc;
}

function encodeStr(rawStr) { return rawStr.replace(/[\u00A0-\u9999<>\&]/gim,   
    function(i){
    return '&#'+i.charCodeAt(0)+';'
  });
}

document.getElementById('xslText').innerHTML = encodeStr(xsl);
document.getElementById('result').innerHTML = encodeStr((new XMLSerializer).serializeToString(result));

HTML:

<pre id='xslText'>

</pre>

<pre id='result'>

</pre>

<pre id='error'>

</pre>

1 个答案:

答案 0 :(得分:1)

在XSLT 1.0中,您需要使用扩展功能,例如exsl:node-sethttp://exslt.org/exsl/functions/node-set/index.html),将类型为结果树片段(https://www.w3.org/TR/xslt-10/#section-Result-Tree-Fragments)的变量值转换为要设置的节点集。能够在节点上使用XPath,例如

var xml = [
    '<p xmlns="http://www.w3.org/1999/xhtml">',
    '<\/p>'
    ].join('\n');

var xsl = [
    '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" xmlns:msxml="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="exsl msxml">',
    '<xsl:variable name="xmlVar">',
    '<aaaa value="It works"/>',
    '<\/xsl:variable>',
    '<xsl:template match="/">',
    '<div>',
    '<xsl:choose><xsl:when test="function-available(\'exsl:node-set\')"><xsl:value-of select="exsl:node-set($xmlVar)/aaaa/@value"/><\/xsl:when><xsl:when test="function-available(\'msxml:node-set\')"><xsl:value-of select="msxml:node-set($xmlVar)/aaaa/@value"/><\/xsl:when><\/xsl:choose>',
    '<\/div>',
    '<\/xsl:template>',
    '<\/xsl:stylesheet>'
    ].join('\n');



var domParser = new DOMParser();

var xmlDoc = domParser.parseFromString(xml, 'application/xml');

var xslDoc = domParser.parseFromString(xsl, 'application/xml');

var xsltProc = new XSLTProcessor();
xsltProc.importStylesheet(xslDoc);
try{
var result = xsltProc.transformToFragment(xmlDoc, document);
document.getElementById('result').appendChild(result);
} catch(exc) {
document.getElementById('error').innerHTML = exc;
}
<pre id='xslText'>

</pre>

<pre id='result'>

</pre>

<pre id='error'>

</pre>

就跨浏览器与客户端XSLT 1的兼容性而言,缺点是Microsoft在IE和Edge中使用MSXML 3或6提供XSLT支持,但不幸的是,MSXML具有其专有的命名空间来支持这种扩展功能,而不是支持EXSLT。

小提琴已更新为http://jsfiddle.net/29pwf84c/14/