2009-08-12 81 views
0

我試圖創造一種通用的XML解析器,像這樣的:1jQuery的範圍問題

部分:

與過濾的對象被創建:

var product = { 

    holder : { 
    id: '', 
    title: '', 
    text : '', 
    price: '' 
    }, 

    filter : { 
    id: '', 
    test: function(elementHolder) { 
     if(elementHolder.id == product.filter.id) { 
     return true; 
     } 
     return false; 
    } 
    } 
} 

第2部分:

XML解析器:

/* 
* Generic XML parser 
* Parses the url into elementHolder objects 
*/ 
var xmlParser = { 

    parseXml: function(url, node, element, functie) { 

    var i = 0;  // result counter 

    var result = []; // the result array 
    /* 
    * Open the xml file 
    */ 
    jQuery.get(url, function(data){ 

     /* 
     * Loop through the results, if we have a filter, apply it. 
     */ 
     jQuery(data).find(node).each(function(){ 
     /* 
     * Copy the element holder 
     */ 
     var elementHolder = element.holder; 
     var elementData = jQuery(this); 

     /* 
     * Fill the copied holder with the xml data 
     */ 
     elementData.children().each(function() { 
      elementHolder[ this.nodeName ] = jQuery(this).text(); 
     }); 

     /* 
     * if the filter applies, add the holder to the result 
     */ 
     if(element.filter.test(elementHolder)) { 
      result[i] = elementHolder; $i++; 
     }   

     // console.log(result); 

     }); 

     /* 
     * If there is a callback (prevents the result from parsing before it is ready) 
     */ 
     try { 
     if (typeof functie == "undefined") { 
      throw 'There is no callback function specified.'; 
     } 
     } catch(e) { alert(e); return; } 

     functie(result); 

    });  

    } 

} 

3部分:

調用的文件準備:

product.filter.id = 11; 

    /* 
    * parsen 
    */ 
    var productXml = 'test.xml'; 
    xmlParser.parseXml(productXml, "product", product, function(data) { 
    console.log('result:'); 
    console.log(data); 
    }); 

第4部分:

的的test.xml:

<data> 
    <products> 
    <product> 
     <id>1</id> 
     <title>test 1</title> 
     <text>text 1</text> 
     <price>1.00</price> 
    </product> 
    <product> 
     <id>2</id> 
     <title>test 2</title> 
     <text>text 2</text> 
     <price>2.00</price> 
    </product> 
    <product> 
     <id>3</id> 
     <title>test 3</title> 
     <text>text 3</text> 
     <price>3.00</price> 
    </product> 
    </products> 
</data> 

它所有的工作,除了一件事罰款;

結果被新創建的持有者覆蓋每個循環,有沒有人有任何想法如何解決這個問題? (我認爲它的確與範圍有關)。

謝謝!

回答

1

我找到了解決辦法

的部分:

var elementHolder = element.holder; 

犯規創建對象的副本,只是一個參考;

,我發現這個頁面上的解決方案是:

http://my.opera.com/GreyWyvern/blog/show.dml/1725165

Object.prototype.clone = function() { 
    var newObj = (this instanceof Array) ? [] : {}; 
    for (i in this) { 
    if (i == 'clone') continue; 
    if (this[i] && typeof this[i] == "object") { 
     newObj[i] = this[i].clone(); 
    } else newObj[i] = this[i] 
    } return newObj; 
}; 

var elementHolder = element.holder.clone(); 
+0

這個函數會使用firefox,它甚至可以使用這個函數: function clone(obj)if(obj == null || typeof(obj)!='object') return obj; var temp = new obj.constructor(); (var key in obj) temp [key] = clone(obj [key]); return temp; } – FrankBr 2009-08-13 07:10:46

0

在黑暗中刺傷 - 但我認爲你需要在內循環中關閉。

改變這種

elementData.children().each(function() { 
    elementHolder[ this.nodeName ] = jQuery(this).text(); 
}); 

這個

elementData.children().each(function(e, n, t) { 
    return function() 
    { 
    e[n] = t; 
    } 
}(elementHolder, this.nodeName, jQuery(this).text())); 
+0

好了,說部分: elementData.children()每個(函數(){ elementHolder [此.nodeName] = jQuery(this).text(); }); 確實有效,替換代碼提供了空對象,它是否真的解決了傳入結果div的對象被覆蓋的問題? – FrankBr 2009-08-12 14:35:55