【问题标题】:Parsing XML JQuery Ajax Response with Namespace使用命名空间解析 XML JQuery Ajax 响应
【发布时间】:2012-03-26 09:33:12
【问题描述】:

我正在使用 JQuery 执行 Web 服务调用,它是 ajax 函数,我无法解析返回的数据。当我警告数据时 (alert($(data).find("return").text()) 它是空的。我看到服务器响应如下所述的 xml 数据,当我警告(数据)时,我得到 [object XMLDocument ]. txt = $(data).find("return").text() 是否有效,因为我的 XML 结构具有下面的命名空间?我可以在 firebug 中看到完整的 xml 字符串。有什么想法吗?

var txt = $(data).find("ns1\:return").text();适用于 Chrome 和 Firefox,但不适用于 Safari

index.js:

$(function () {
$.ajax({
                url: url,
                success: function (data) {
                    var ndx = 0,
                        row,
                        **txt = $(data).find("return").text(),**
                        xml = unescape(txt),
                        xmlDoc = $.parseXML(xml),
                        firstrow = $(xmlDoc).find(
                                "results").children(":first");

                    // populate the table based on the results returned by
                    // the web service
                    $("table.results thead").empty();
                    $("table.results tbody").empty();
                    row = $("<tr/>");

                    row.append($("<th/>").text("#").addClass("ndx"));
                    firstrow.children().each(function () {
                        row.append($("<th/>").text(this.nodeName));
                    });
                    row.appendTo($("table.results thead"));

                    $(xmlDoc).find("row").each(function () {
                        row = $("<tr/>");
                        row.append($("<td/>").text(ndx + 1).addClass("ndx"));
                        $(this).children().each(function () {
                            row.append($("<td/>").text($(this).text()));
                        });
                        row.appendTo($("table.results tbody"));
                        ndx++;
                    });

                    // clear the table if no results were returned
                    if (ndx == 0) {
                        // no rows returned
                        $("table.results thead").empty();
                        $("table.results tbody").empty();
                    }

                    statusNotice("Records Returned: " + ndx);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    // display the error returned by the web service
                    var xmlDoc = $(XMLHttpRequest.responseXML);
                    statusError(xmlDoc.find("Text").text());
                },          
                complete: function(XMLHttpRequest, textStatus) {
                    // hide the busy dialog
                    $("#busy-dlg").dialog("close");
                }
            });
       });

index.html: 演示

<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-min.js"></script>
<script type="text/javascript" src="js/jquery.layout-latest.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</head>
<body>
//table displaying results from ajax call here
</body>
</html>

XML:

<ns1:executeResponse xmlns:ns1="http://sqlws.test.com">
<ns1:return>
    <results>
        <row>
            <attribute1>value1</attribute1>
            <attribute2>value2</attribute2>
        </row>
        <row>
            <attribute1>value1</attribute1>
            <attribute2>value2</attribute2>
        </row>
    </results>
</ns1:return>
</ns1:executeResponse> 

【问题讨论】:

  • XML 结构无效,&lt;attribute1&gt;&lt;/atribute1&gt; 不匹配(结束标记中缺少t)。
  • @RobW - 这是一个错字现已修正。

标签: javascript jquery ajax


【解决方案1】:

当元素以命名空间为前缀时,您必须也添加命名空间:

  • .find('ns1:return') 不起作用,因为 : 被 jQuery 用作伪选择器。
  • .find('ns1\:return') 也不起作用,因为字符串中的单个反斜杠用作转义字符。 "ns1\:return" 变为 "ns1:return" 等于前一个。
  • 应该使用 .find('ns1\\:return')。双反斜杠用于转义冒号。

似乎最后一个解决方案在 IE 和 Firefox 中运行良好,但在 Opera、Chrome 或 Safari 中却不行。为了获得最大的兼容性,请使用带有和不带有假前缀的 jQuery 选择器,即。 "ns1\\:return, return" 而不是普通的 ns1\\:return

演示:http://jsfiddle.net/5BQjv/51/

// For example, this is the result:
var data = '<ns1:executeResponse xmlns:ns1="http://sqlws.test.com">' +
               '<ns1:return>' + 
                   '<results> <row> ... </row> </results>' +
               '</ns1:return>' +
           '</ns1:executeResponse>';

// The very first thing is to parse the string as XML. NOT later!
var $xmlDoc = $($.parseXML(data));

// Then, look for the element with the namespace:
var $txt = $xmlDoc.find('ns1\\:return, return');

// No need to use unescape or something, just use DOM manipulation:
// `results` is the immediate child. Don't use .find, but .children
var $firstrow = $txt.children("results").children(":first");

您可能已经注意到,我在一些变量前面加上了美元符号。为引用 jQuery 对象的变量加上美元符号前缀是惯例,以避免在开发期间/之后造成混淆。

【讨论】:

  • 太棒了。谢谢你把我从几个小时可能毫无结果的胡闹中解救出来。
  • 这很棒,但很假。您的解决方案所做的是查询命名空间 PREFIXES,这与命名空间不同。 ns1 是前缀,在您的情况下,它指的是命名空间http://sqltest.test.com。到目前为止,我还没有看到任何真正正确处理命名空间的解决方案,只有显示如何处理命名空间前缀的答案。问题是当文档格式发生变化时,命名空间前缀可能会发生变化(或者可能完全不存在),但从 XML 信息集的角度来看,文档是完全等效的。
  • @dizel3d 更新了答案并针对其他浏览器进行了测试。
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 2015-09-08
  • 2019-04-21
  • 2012-12-05
  • 2021-05-03
  • 2014-01-10
  • 2010-11-08
相关资源
最近更新 更多