在IE浏览器中,outerHTML未定义

7

我的代码通过Ajax调用获取JSON,其中包含XML,并通过读取其中的一些信息来处理它。

虽然在Chrome中解析XML运行良好,但在IE中却不行,因为在IE中outerHTML 返回undefined

我已经阅读了几篇帖子并尝试了几个可能的解决方案,但都没有成功。

JavaScript代码如下:

$.ajax({
    url: 'getJSONwithXML.do',
    type:'POST',
    data:'',
    dataType: 'json',
    cache: false
}).done(function(data) {
    var jsonResp = JSON.parse(data.data.respuesta);
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(jsonResp,"text/xml");
    var texto = $(xmlDoc).find('texto').prop('outerHTML');
    console.log(texto); // <--- undefined in IE
    $('body').append('<div>' + texto + '</div>');
});

我在jsonResp下得到的XML如下所示:
<?xml version="1.0" encoding="UTF-16"?>
<envio>
    <version>1.0.0</version>
    <anuncios>
        <remitente>
            <nodoRemitente>Nodo Remitente</nodoRemitente>
        </remitente>
        <anuncio>
            <emisor>
                <nodoEmisor>Nodo Emisor</nodoEmisor>
            </emisor>
            <metadatos>
                <id>16249</id>
            </metadatos>
            <contenido>
                <texto>
                    <p>
                        Notificación de prueba
                    </p>
                    <p>
                        Notificación de prueba
                    </p>
                    <p>
                        Notificación de prueba
                    </p>
                </texto>
            </contenido>
        </anuncio>
    </anuncios>
</envio>

在Chrome或Fireforx中,texto返回:
<texto>
    <p>
        Notificación de prueba
    </p>
    <p>
        Notificación de prueba
    </p>
    <p>
        Notificación de prueba
    </p>
</texto>

我想要的是texto标签内的HTML代码,在Internet Explorer浏览器中却返回了undefined

我已经尝试使用textContent属性,但它并不返回HTML代码。

有什么想法吗?


如果您能提供一个XML的最小示例,那将是最好的。大家都在猜测,这很好,但要得到一个确切的答案,就需要知道结构是什么样子的。此外,$(this).find('texto')永远不会返回undefined,只会返回一个jQuery对象,其长度为0。 - Heretic Monkey
非常感谢您就代码改进提供的建议。我已经进行了更新。我还编辑了我的问题,并提供了在jsonResp下获得的xml字符串。 - bentakayze
3个回答

18

在XML文档中,Internet Explorer不提供节点的outerHTML属性(也不提供innerHTML)。您可以使用XMLSerializer(在IE 9+中可用)解决该问题:

var node = $(xml).find('texto')[0]; // get DOM node
// Try outerHTML. If not available, use XMLSerializer
var texto = node.outerHTML || new XMLSerializer().serializeToString(node);

请注意,texto 字符串可能会为根节点获取 xmlns 属性。但我认为这对您使用它的方式没有影响。


非常感谢@trincot!!你建议的方法非常有效!! - bentakayze
@codenamezero,确实。我已经删除了对IE11的引用。 - trincot

0

因为您使用的是JQuery(而不是返回单个DOM元素的标准DOM API方法),所以您的所有JQuery查询都将返回至少一个JQuery包装集。该包装集可能已填充或未填充,因此您不应该测试包装集的存在,而应该测试其内容。这可以通过检查集合的length来完成。

此外,您用于确保要获取outerHTML的元素有点复杂。当您测试typeof时,您将获得"undefined"(作为字符串),因此请确保在测试undefined作为字符串时使用它。

请参见此示例:

// There is no element with an id of "special" in this DOM
var result = $("#special");

// But, the JQuery query will still return a "wrapped set" container object
console.log(result === null);                         // false - there is a wrapped set

// You need to test for what's in the container:
console.log(result.length > 0);                       // false - the set is empty
console.log(typeof result[0] === "undefined");        // true  - nothing exists at position 0
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

所以你的代码应该检查长度length。只要记住,在if条件中使用0length是“falsey”,会转换为false,而任何其他值都是“truthy”并将转换为true
if($(this).find('texto').length){
  debugger;
  var texto = $(this).find('texto').prop('outerHTML');
  .  . .
}

但是,由于您可能需要多次访问该包装集合,因此您可以使用:

var el = $(this).find('texto');

if(el.length){
  debugger;
  var texto = el.prop('outerHTML');
  .  . .
}

如果你去掉“not”的部分,使其变成“or”,那么你需要将其变为“and” - 这就像说1+1=2应该是2=1+1。 - freedomn-m
@freedomn-m 是的,那是我的最初想法 - Scott,我认为你的“应该是”部分与 OP 的代码没有任何区别。尽管我同意最后的片段是简单、优雅的解决方案! - Tyler Roper
1
if ($(this).find('texto')) will always return true. You need if ($(this).find('texto').length>0) (the code in the answer should be if (el.length>0) - freedomn-m
@freedomn-m 是的,说得好。我已经更新了答案来考虑这一点。 - Scott Marcus
1
非常感谢您对代码改进方面的建议,但问题在于,无论我如何检查 $(this).find('texto'),在 Chrome 和 Firefox 中,我都可以从 $(this).find('texto').prop('outerHTML') 获取所需内容,但这在 Explorer 中不起作用。 - bentakayze

0

我认为问题在于您正在将jQuery的HTML方法与XML下的基础DOMParser混合使用。$(this).find(...)在各个版本的IE中都会做很多工作,以解决其不稳定的文档模型,但其中许多与XML不兼容。

IE支持XML,但存在自定义元素的问题,因此<texto>在XML中是可以的,但在HTML5中无法识别。

要确定确切的jQuery版本和IE当前使用的文档模型(基于文档声明),我们需要进入细节。

然而,一个简单的解决方法是要么将jQuery替换为XML解析步骤,要么从本地的DOMParser切换到$.parseXML

我建议首先尝试前者-用this.getElementsByTagName(...)替换所有的$(this).find(...)


@freedomn-m 这不是微小的优化(如果我们要这样做,我会首先不使用jQuery)- outerHTML 是一个DOM元素属性,而不是jQuery函数。 $texto[0] 只是一种获取DOM元素而不是包装器以直接调用该属性的方法。 - Keith
@bentakayze,我根据问题的澄清重新编写了答案。我认为这是IE的DOM解析器和XML的问题。 - Keith
我也尝试了你的解决方案,但在Explorer浏览器中仍然得到了“未定义”的文本。检查$texto[0]时,没有这样的方法或属性。没有outerHTMLhtml() - bentakayze
@bentakayze 我已经重新写了答案。 - Keith
好的。非常感谢。我会按照您的建议再试一次。 - bentakayze
非常感谢@Keith的建议,但是trincot提出的建议起作用了。 - bentakayze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接