【问题标题】:Why does XSLT add newline (carriage return) in IE10为什么 XSLT 在 IE10 中添加换行符(回车)
【发布时间】:2013-08-07 21:33:24
【问题描述】:

据我所知,这只是从 IE10 开始。

在 FF 中这不是问题。

使用 XMLHttpRequest 获取一些 xml 数据,然后使用 xslt 显示出来...

xslt 转换会自动在元素数据中有空格的看似随机的位置添加新行。

如果我使用 getElementsByTagName 预览数据,数据是完整的,没有空格被转换为换行符。

由于 html 将新行视为空格,因此如果您只是显示文本或将其放在输入框中,则看不到问题,但是,如果数据存储在隐藏元素中并使用警报显示它函数可以看到输出数据中有换行符/回车符。

如果原始 xml 数据中的元素后没有回车,问题似乎会更糟。在某些情况下,我实际上可以通过在每个元素后添加一个回车来解决这个问题。有些情况,不是全部。

就好像当转换器试图读取数据时,它会在空格处分割数据以提高可读性,并自动添加回车。

例子:

xsltTest.htm

<!DOCTYPE html>
<html>
<head>
    <title>xslt test</title>
    <script type="text/javascript" language="javascript">

        function loadFile(f) {
            xhttp = new window.XMLHttpRequest
            xhttp.open("GET", f, false)
            xhttp.setRequestHeader("Cache-Control", "no-cache");
            xhttp.setRequestHeader("pragma", "no-cache");
            xhttp.send("")

            //in IE10 this seems to show where the new lines get added
            alert(xhttp.responseText)

            var xml = xhttp.responseXML

            displayData(xml, 'xsltTest.xslt', 'DataDiv')

        }

        function displayData(xmlResp, xslFile, targetObj) {

            var xml = new ActiveXObject("MSXML2.DomDocument");
            xml.async = false;
            xml.load(xmlResp);

            var xsl = new ActiveXObject("MSXML2.FreeThreadedDomDocument");
            xsl.async = false;
            xsl.load(xslFile);

            xsl_template = new ActiveXObject("Msxml2.XSLTemplate")
            xsl_template.stylesheet = xsl;

            xslProc = xsl_template.createProcessor()
            xslProc.input = xml

            xslProc.transform()
            document.getElementById(targetObj).innerHTML = xslProc.output
        }

        function popData(idx,e) {
            alert(document.getElementById('data_'+idx+'_'+e).value)
        }

    </script>
</head>
<body>
<center>
<input type="button" id="WithCRButton" value="Load File WITH CarriageReturns" onclick="loadFile('DataWithCR.xml')" />
<input type="button" id="WithoutCRButton" value="Load File WITHOUT CarriageReturns" onclick="loadFile('DataWithoutCR.xml')" />
<div style="border:1px solid black;width:100%" id="DataDiv">
</div>
</center>
</body>
</html>

xsltTest.xslt

<?xml version="1.0" encoding="iso-8859-1"?>

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema">


    <xsl:template match="/">
        <table>
            <xsl:for-each select="TestData/field">
                <tr>
                    <td>
                        <xsl:value-of select="elementData1"/>
                    </td>
                    <td>
                        <input type="hidden">
                            <xsl:attribute name="value"><xsl:value-of select="elementData1"/></xsl:attribute>
                            <xsl:attribute name="id">data_<xsl:value-of select="position()"/>_1</xsl:attribute>
                        </input>
                        <input type="button" value="show hidden value">
                            <xsl:attribute name="onclick">popData('<xsl:value-of select="position()"/>','1')</xsl:attribute>
                        </input>
                    </td>
                    <td>
                        <xsl:value-of select="elementData2"/>
                    </td>
                    <td>
                        <input type="hidden">
                            <xsl:attribute name="value"><xsl:value-of select="elementData2"/></xsl:attribute>
                            <xsl:attribute name="id">data_<xsl:value-of select="position()"/>_2</xsl:attribute>
                        </input>
                        <input type="button" value="show hidden value">
                            <xsl:attribute name="onclick">popData('<xsl:value-of select="position()"/>','2')</xsl:attribute>
                        </input>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>

</xsl:stylesheet>

DataWithCR.xml

<TestData>
<field>
<elementData1>ThisHasNoSpaces</elementData1>
<elementData2>ThisHasA Space</elementData2>
</field>
<field>
<elementData1>ThisHasNoSpaces</elementData1>
<elementData2>ThisHasA Space</elementData2>
</field>
<field>
<elementData1>ThisHasNoSpaces</elementData1>
<elementData2>ThisHasA Space</elementData2>
</field>
<field>
<elementData1>ThisHasNoSpaces</elementData1>
<elementData2>ThisHasA Space</elementData2>
</field>
</TestData>

DataWithoutCR.xml

<TestData><field><elementData1>ThisHasNoSpaces</elementData1><elementData2>ThisHasA Space</elementData2></field><field><elementData1>ThisHasNoSpaces</elementData1><elementData2>ThisHasA Space</elementData2></field><field><elementData1>ThisHasNoSpaces</elementData1><elementData2>ThisHasA Space</elementData2></field><field><elementData1>ThisHasNoSpaces</elementData1><elementData2>ThisHasA Space</elementData2></field></TestData>

【问题讨论】:

  • 在样式表中 &lt;xsl:template match="/"&gt; 之前添加 &lt;xsl:output method="xml" indent="no"/&gt; 是否有帮助?
  • 你能输入输出的实际内容和应该是什么吗?
  • 输出很难包含,但是发生的情况是,当警报框显示数据“ThisHasA Space”时,“A”和“Space”之间有一个回车,不在原始数据。
  • @FrankPl,不,添加 "" 没有帮助。
  • 这可能与您无关(您没有在问题中提到 Chrome),但我想您可能想知道 Chrome 开发人员正在考虑在未来版本中放弃对 XSLT 的支持理由是没有人再使用它了,因为它很难使用,而且所有浏览器的支持都很差。如果您以后需要 XSLT 支持,您应该考虑加入他们的邮件列表并听取您的意见。

标签: javascript xml internet-explorer xslt


【解决方案1】:

我发现如果我使用“ActiveXObject("Msxml2.XMLHTTP")”而不是“window.XMLHttpRequest”,问题就会消失。

似乎微软刚刚实现了浏览器原生的“window.XMLHttpRequest”......但它有错误和限制。

例如,"ActiveXObject("Msxml2.XMLHTTP")" 有 transformNode 方法,但"window.XMLHttpRequest" 没有。

为了我的 javascript 代码中的浏览器兼容性,我创建对象如下:

var XMLDoc = (window.XMLHttpRequest) ? (new XMLHttpRequest()) : (new ActiveXObject("Microsoft.XMLHTTP"))

...所以在 IE 中,只要 window.XMLHttpRequest 不存在,它就会使用 ActiveXObject。但现在它确实存在,它正在使用它,以及它的所有错误和限制。

我现在正在反转那个条件语句,如果它可用的话,它调用默认为 ActiveXObject...

var XMLDoc = (window.ActiveXObject) ? (new ActiveXObject("Msxml2.XMLHTTP")) : (new XMLHttpRequest())

【讨论】:

  • 没有transform 方法不是限制,甚至the spec 中都没有此方法。 Microsoft 根据该规范实现了XMLHttpRequest API。这就是为什么 XSLT 要在服务器上运行的原因之一。不要做客户端 XSLT。
  • 在某些情况下客户端更可取。例如,当下载了大量数据并且您只想为用户重新整理或重新排列数据时。因此,即使我们忘记了 transformNode 而只是坚持将回车引入数据的原始问题。这是完全不能接受的。又一个 MS/IE 错误。再次斯克鲁德。
  • 我已经广泛使用 MSXML(后台库),我从未见过在代码中插入空白节点(即换行符)除非@987654327 @ 已设置或它们已经存在于输入中。我很确定错误在您的最后,可能是由于不正确的实施或错误的期望。无论如何,我将使用您在上面提供的示例代码设置一个测试用例,并告诉您我的发现。
  • 好吧,这就是我的发现:你是对的,我错了。空白节点插入到文档中。此行为的关键是preserveWhiteSpace property,默认为false。您可以在send() 请求之前使用xhttp.responseXML.preserveWhiteSpace = true; 设置它。 但是,无论此设置如何,您的 XSLT 代码生成的输出都应该(并且是!)相同,因为它只会影响 无关紧要 的空白,而这些东西是您永远不应该关心的或无论如何使用。
  • 所以我不明白的是 - 除了 responseXML.xml 属性与输入文档不完全一样 - 这种行为到底有什么问题?
猜你喜欢
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多