Internet Explorer使用XSL处理器添加换行符

时间:2016-08-17 08:33:52

标签: javascript html xml internet-explorer xslt

正如一些背景我有一个应用程序,它部分地采用XML片段并使用XSL模板处理它以给我一个HTML输出。

为了让它在IE中运行,我添加了这段代码:

    var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE ");
        if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
            var xslt = new ActiveXObject("Msxml2.XSLTemplate");
            var zxsl_activex = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
            zxsl_activex.async = false;
            zxsl_activex.load("/ZymonicBlockCombined.xsl");
            xslt.stylesheet = zxsl_activex;
            var xsl_proc = xslt.createProcessor();
            if ( xml instanceof Document ) { xsl_proc.input = xml; }
            else { xsl_proc.input = xml.ownerDocument; }
            xsl_proc.transform();
            return document.createRange().createContextualFragment(xsl_proc.output);

这篇文章的礼貌是: Object doesn't support property or method 'transformNode' in Internet Explorer 10 (Windows 8)

我遇到的问题是转换为片段(xsl_proc.output)的字符串中包含随机换行符,必须在transform()函数中的某处添加。例如,当您在控制台中查看字符串时,它看起来像这样:

alidationResults.push(basic_validation( “1453_dept_id”,“区

2位数ID“,”char“,”“,2,[”[[display_name]]

这当然意味着当浏览器尝试将此片段插入页面并运行脚本时,会出现“未终止字符串常量”错误。

问题是 - 有没有办法阻止transform()函数添加额外的换行符?

我想指出输入xml对象没有这些额外的换行符,而FireFox XSLTProcessor的输出也没有。

我也尝试从字符串中删除换行符(这非常简单),但当然无法确定换行符是否在“原始”xml中,或者它是否是其中一个,所以这也行不通。

编辑:

完整的“转化”方法如下:

   function TransformXML(xml) {

var xsl = window.zxsl;
// FireFox, Safari, Chrome, Opera etc.
if (typeof (XSLTProcessor) != "undefined") { 
    var xslt_processor = new XSLTProcessor();
    xslt_processor.importStylesheet(xsl);
    return xslt_processor.transformToFragment(xml, document);
}

// IE8 and below
if (typeof (xml.transformNode) != "undefined") { 
    return xml.transformNode(xsl);
}

// IE9 onwards
else {
    try { 
        // This checks for all versions of IE up to 11, may need to change in future
        var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE ");
        if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
            var xslt = new ActiveXObject("Msxml2.XSLTemplate");
            var zxsl_activex = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
            zxsl_activex.async = false;
            zxsl_activex.load("/ZymonicBlockCombined.xsl");
            xslt.stylesheet = zxsl_activex;
            var xsl_proc = xslt.createProcessor();
            if ( xml instanceof Document ) { xsl_proc.input = xml; }
            else { xsl_proc.input = xml.ownerDocument; }
            xsl_proc.transform();
            return document.createRange().createContextualFragment(xsl_proc.output);
        }
    }
    catch (e) {
        alert("The type [XSLTProcessor] and the function [XmlDocument.transformNode] are not supported by this browser, can't transform XML document to HTML string!");
        return null;
    }
}
}

我知道并不是特别有帮助,我试图为它设置一个jsFiddle但不幸的是它不支持ActiveXObjects所以我不知道如何提供更多信息。

XML只是一个通用片段:

<report expanded="true" group_ident="ebex_performance_filter_zztlg" has_headers="true" ident="277_ebex_performance_filter_zztlg" block_id="277" blockid="277" filter_ident="277_ebex_performance_filter_">
<result ident="277_ebex_performance_filter_zztlg_0_result">
<report expanded="false" group_ident="277_ebex_performance_filter_epf_all_g" ident="277_ebex_performance_filter_zztlg_0_result_epf_all_g" result_count="0">
<navigation current_page="1" first_page="1" last_page="1" next_page="1" previous_page="1" results_per_page="1">
<error>Maximum number of results allowed is 1.</error>
</navigation>
</report>
<zz_top_level_group_field DisplayOnly="true" DisplayOrder="1" LinkField="true" ReportMode="true" ident="277_ebex_performance_filter_zztlg_0_result_field" type="Field">
<DisplayName>All</DisplayName>
</zz_top_level_group_field>
</result>
</report>

同样,任何xsl文件/片段都会重新创建它(因为问题是xsl_proc.transform())。

1 个答案:

答案 0 :(得分:0)

对于将来可能访问此页面的任何人,我最终自己解决了这个问题。 从这篇文章中可以看出,你需要在转换之前将xml上的'preserveWhiteSpace'属性设置为true。 Why does XSLT add newline (carriage return) in IE10

为了做到这一点,我发现你需要一个ActiveXObject,所以我创建了一个ActiveX并将我的XML加载到其中:

size

请注意,我传入的xml是Document或Object(因此是三元条件),然后我将其序列化为一个字符串,以加载到xml axtivexobject中。

代码现在看起来像这样(并且做我需要做的事情):

var value = document.getElementsByName('__Token')[0].value;