2009-08-12 5 views
0

Ich versuche, eine Art von generischen XML-Parser zu erstellen, wie folgt aus:jQuery Rahmen Problem

Teil 1:

Ein Objekt mit Filter erstellt:

var product = { 

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

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

Teil 2:

Der xML-Parser:

/* 
* 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); 

    });  

    } 

} 

Teil 3:

Aufruf auf Dokument bereit:

product.filter.id = 11; 

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

Teil 4:

Die 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> 

Alles in Ordnung, außer für eine Sache funktioniert;

Das Ergebnis wird jede Schleife von dem neu erstellten Halter überschrieben, hat jemand irgendwelche Ideen, wie das zu beheben? (Ich denke, es hat etwas mit dem Umfang zu tun).

Danke!

Antwort

1

ich die Lösung gefunden

Der Teil:

var elementHolder = element.holder; 

Doesnt eine Kopie des Objekts erstellen, nur ein weiterer Referenz;

fand ich die Lösung, dass auf dieser Seite:

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

Diese Funktion bugs Firefox, es ist noch besser, diese Funktion zu verwenden: Funktion Klon (Obj) { if (obj == null || typeof (obj)! = 'Objekt') return obj; var temp = neuer obj.constructor(); für (Var-Schlüssel in Obj) Temp [Schlüssel] = Klon (Obj [Schlüssel]); Rücklauftemp; } – FrankBr

0

Stab im Dunkeln - aber ich denke, Sie brauchen einen Verschluss in Ihrer inneren Schleife.

Änderung dieser

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

dieser

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

Nun, der Teil, der sagt:. elementData.children() jede (function() { elementHolder [diese .nodeName] = jQuery (this) .text(); }); funktioniert, der Ersetzungscode bietet leere Objekte, sollte es wirklich das Problem lösen, dass das Objekt, das in das Ergebnisdiv übergeben wird, überschrieben wird? – FrankBr