0

我需要解析一个“first.xml”,在这个解析函数中,我必须为“first.xml”中的每个元素解析一个“second.xml”。看起来 jQuery 在解析“first.xml”之前不会解析“second.xml”。

我的 HTML 文件有一个 div,其中附加了内容:

<div id="Content"></div>

整个代码嵌入在 $(document).ready(function({});

function parseXML(xmlFilePath, callback){
    $.ajax({
        type: "GET",
        url: xmlFilePath,
        dataType: "xml",
        success: function(xml) {
            callback(xml);
        }
    });
}

parseXML("first.xml", function(returnedXML){
    $(returnedXML).find("ElementA").each(function(counter) {

        name_of_Attribute_of_Element_A = $(this).attr("name");
        $("#Content").append(counter  + ". " + name_of_Attribute_of_Element_A);

        $("#Content").append("------ before parsing second.xml ------");

        parseXML("second.xml", function(returnedXML){
            $(returnedXML).find("ElementB").each(function() {
                name_of_Attribute_of_Element_B = $(this).attr("name");
                $("#Content").append(name_of_Attribute_of_Element_B);
            });
        });


    });

});

我的输出看起来像这样:

1. name_of_Attribute_of_Element_A
------ before parsing second.xml ------
2. name_of_Attribute_of_Element_A
----- before parsing second.xml ------
3. name_of_Attribute_of_Element_A
----- before parsing second.xml ------
name_of_Attribute_of_Element_B
name_of_Attribute_of_Element_B
name_of_Attribute_of_Element_B

代替:

1. name_of_Attribute_of_Element_A
------ before parsing second.xml ------
name_of_Attribute_of_Element_B
2. name_of_Attribute_of_Element_A
----- before parsing second.xml ------
name_of_Attribute_of_Element_B
3. name_of_Attribute_of_Element_A
----- before parsing second.xml ------    
name_of_Attribute_of_Element_B

我还尝试连接我的输出,最后只附加一次。这意味着而不是

$("#Content").append(result);

我用过

myHTMLOutput = myHTMLOutput + result;

在我使用的文件的末尾

$("#Content").append(myHTMLOutput);

一次,但结果相同。

是不是 jQquery 不允许使用 Ajax 多次解析 XML 文件?如果是这样,是否可以选择中断第一个文件的解析,完成第二个文件的解析并恢复第一个文件的解析?

奇怪的细节:如果我使用 JetBrains Webstorm 调试我的代码,则逐步输出是正确的。只有当我正常运行它时,才会在“first.xml”之后附加“second.xml”的输出。

提前感谢您提供的任何帮助。

4

2 回答 2

0

我认为问题出在each()and中find()。您循环遍历所有“ElementA”(这很快,因为 xml 1 号已经完成),而第二个 ajax 调用需要时间来完成。因此显示了第一个 xml 的元素,并触发了 second.xml 的 ajax,但要花时间进行 ajax 往返,因此您会得到它们。

一个可能的解决方案是不同的逻辑:

parseXML("first.xml", firstCallback);

var counter = 0;
var max;

function firstCallback(xml)
{
    var a = $(xml).find("ElementA");
    max = a.length;
    // do something with elements of first.xml
    readSecond();
}

function readSecond(xml)
{
    // do something with elements of second.xml
    if (counter==max) return;
    parseXML("second.xml",readSecond);
    counter++;
}

不过,我还没有测试过这段代码,希望我没问题。

于 2012-06-19T22:44:09.763 回答
0

您遇到的基本问题是 ajax 中的“A”......“异步”。第一个 xml lopp 在从辅助调用接收到所有数据之前完成。

这是一个使用存储在数组中的 jQuery 延迟的解决方案。内容在到达时存储在对象中。每个 A 项目中的某些 B 项目仍有可能出现故障,但 B 将始终与正确的 A 在一起。

概念嵌套$.when( B ).done()$.when( A ).done()其中,此时它将内容对象解析为 DOM。

由于小提琴要求,使用 $.post

演示:http: //jsfiddle.net/Dt75U/

/* store all ajax content in object*/
var content = {};

function parseContent(content) {
    $.each(content, function() {
        $('body').append('<br><br>' + this.a + '<br>' + this.b.join('<br>'));
    })
}
/* array to store nested ajax promises */
var deferreds_b = [];
/* A promise and ajax*/    
var xml_A = $.post("/echo/xml/", {
    xml: a
}, function(returnedXML) {

    var $el_A = $(returnedXML).find("ElementA");
    var total_A = $el_A.length;
    $el_A.each(function(counter) {
        var countA = counter;
        var name_of_Attribute_of_Element_A = $(this).attr("name");
        /* create EL A object , store EL A content, create array to push B content to */
        content[countA] = {
            a: countA + ". " + name_of_Attribute_of_Element_A,
            b: []
        }

        var xml_B = $.post("/echo/xml/", {
            xml: b
        }, function(returnedXML) {

            var $el_B = $(returnedXML).find("ElementB");
            var total_B = $el_B.length;
            $el_B.each(function(idx) {
                var name_of_Attribute_of_Element_B = $(this).attr("name");
                content[countA].b.push(countA + ". " + name_of_Attribute_of_Element_B);
            });
        });
    /* push B promise to array*/
        deferreds_b.push(xml_B);


    });
});

$.when(xml_A).done(function() {
    /* when A is done , wait for B to be done*/
    $.when.apply(null, deferreds_b).done(function() {
        parseContent(content);
        $("body").append("<p>All done!</p>");
    });

})
于 2012-06-20T00:49:04.007 回答