Best Practices für AS3, XML-Parsing
Habe ich einige Probleme, analysieren die verschiedenen Arten von XML innerhalb von flash (speziell FeedBurner RSS-Dateien und YouTube Daten API-Antworten). Ich bin mit einem URLLoader
zum laden einer XML-Datei, und auf Event.COMPLETE
erstellen ein neues XML-Objekt. 75% der Zeit, die diese Arbeit gut, und hin und wieder bekomme ich diese Art von Ausnahme:
TypeError: Error #1085: The element type "link" must be terminated by the matching end-tag "</link>".
Wir denken, das problem ist, dass Die XML ist groß, und vielleicht das Event.COMPLETE
Ereignis wird ausgelöst, bevor die XML-Datei tatsächlich heruntergeladen von der URLLoader
. Die einzige Lösung, die wir haben, kommen, ist mit ausschalten ein timer auf das Ereignis, und im wesentlichen "warten Sie ein paar Sekunden", bevor die Daten analysieren. Natürlich kann dies nicht der beste Weg, dies zu tun.
Gibt es eine todsichere Methode zum Parsen von XML innerhalb von Flash?
Update Sept 2 2008 Wir abgeschlossen haben, die folgenden, die excption ausgelöst wird, der code an dieser Stelle:
data = new XML(mainXMLLoader.data);
// calculate the total number of entries.
for each (var i in data.channel.item){
_totalEntries++;
}
Habe ich gelegt, ein try/catch-Anweisung, um dieses Teil, und bin derzeit auf der Anzeige eine Fehlermeldung auf dem Bildschirm, wenn Sie Auftritt. Meine Frage ist, wie würde eine unvollständige Datei an diesen Punkt gelangen, wenn die bytesLoaded == bytesTotal
?
Ich habe aktualisiert die ursprüngliche Frage mit einem status Bericht; ich denke, eine andere Frage wäre gibt es eine Möglichkeit, um zu bestimmen, ob oder nicht eine XML
Objekt wird ordnungsgemäß analysiert, bevor auf die Daten zugreifen (falls der Fehler ist, dass meine Schleife zählt die Anzahl der Objekte ab, bevor die XML-Daten tatsächlich analysiert in dem Objekt)?
@Theo: Danke für die ignoreWhitespace-Tipp. Auch wir haben festgestellt, dass der event wird aufgerufen, bevor Ihr bereit (Wir hatten einige tests, tracing mainXMLLoader.bytesLoaded + "/" + mainXMLLoader.bytesLoaded
InformationsquelleAutor Jeff Winkworth | 2008-08-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie versucht, zu prüfen, dass der Byte, die geladen wurden, sind die gleichen wie die Gesamtanzahl der bytes?
Sollte Ihnen sagen, wenn die Datei fertig geladen ist, wird es nicht helfen, mit der gesammte event feuern zu früh, aber es sollte Ihnen sagen, wenn es ein problem mit dem xml gelesen.
Ich bin nicht sicher, ob es funktionieren wird über domains, wie meine xml ist immer auf der gleichen Seite.
InformationsquelleAutor Re0sless
Über die Sache ist für mich, dass es vielleicht brennen Veranstaltung.Bevor es fertig geladen ist, und das macht mich Wundern, ob oder nicht der laden ist das timing.
Wie oft tritt das problem? Können Sie Erfolg haben, einen moment, dann Versagen die nächsten mit dem gleichen Futter?
Testweise versuchen, die Rückverfolgung der
URLLoader.bytesLoaded
und dieURLLoader.bytesTotal
an der Spitze derEvent.COMPLETE
handler-Methode. Wenn Sie nicht übereinstimmen, wissen Sie, dass das Ereignis brennen vorzeitig. Wenn dies der Fall ist, können Sie hören, für Sie die URLLoader-die progress-Ereignis. Überprüfen Sie diebytesLoaded
gegen diebytesTotal
in Ihrer handler und nur zum Parsen der XML-sobald der laden ist wirklich komplett. Zugegeben, dies ist sehr wahrscheinlich verwandt mit dem, was die URLLoader ist zu tun, bevor es feuertEvent.COMPLETE
, aber wenn das kaputt ist, können Sie versuchen Ihre eigenen Rollen.Bitte lassen Sie uns wissen, was Sie herausfinden. Und wenn Sie könnten, bitte fügen Sie in einigen source-code. Wir könnten in der Lage sein, so etwas beachten.
InformationsquelleAutor Brian Warshaw
Nur eine Randnotiz, diese Anweisung hat keine Wirkung:
weil
ignoreWhitespace
ist eine Eigenschaft. Sie haben, um es zutrue
wie diese:InformationsquelleAutor Theo
Als Sie in Ihrer Frage erwähnt, das problem ist sehr wahrscheinlich, dass Ihr Programm auf der Suche auf die XML-bevor es wurde tatsächlich vollständig heruntergeladen, ich weiß nicht, dass es eine todsichere Methode, um zu "analysieren" die XML-weil der parsing-Teil des Codes wird mehr als wahrscheinlich in Ordnung, es ist einfach eine Frage, ob oder nicht es hat tatsächlich heruntergeladen.
Könnten Sie versuchen, verwenden Sie die ProgressEvent.PROGRESS-Ereignis zu überwachen laufend die XML, wie Sie lädt und dann als Re0sless vorgeschlagen, überprüfen Sie die bytesLoaded-vs die bytesTotal und haben Ihre XML-parse beginnen, wenn die zwei zahlen gleich sind, anstelle der Verwendung der Veranstaltung.COMPLETE-Ereignis.
Sollten Sie in der Lage sein, um die bytesLoaded-und bytesTotal-zahlen nur in Ordnung, unabhängig von Domänen, wenn Sie können auf die Datei zugreifen, können Sie auf dessen byte-Informationen.
InformationsquelleAutor vanhornRF
Wenn du posten könntest etwas mehr code, den wir vielleicht in der Lage sein zu finden, das Problem.
Andere Sache, um zu testen (neben tracing
bytesTotal
) auf die Spur, diedata
- Eigenschaft des loader in derEvent.COMPLETE
handler, nur um zu sehen, wenn die XML-Daten eigentlich korrekt geladen, zum Beispiel überprüfen, dass es eine</link>
es.InformationsquelleAutor Theo
@Brian Warshaw: Dieses Problem tritt nur bei etwa 10-20% der Zeit. Manchmal hat es Schluckauf und einfach Neuladen der app wird funktionieren, andere Male, die ich verbringen eine halbe Stunde Neuladen der app immer und immer wieder ohne Erfolg.
Dies ist der original-code (wenn ich die Frage gestellt habe):
- Und dies ist der code, den ich geschrieben habe basiert auf Re0sless' original-Antwort (ähnlich zu einigen Kommentaren erwähnt):
Werde ich darauf hinweisen, dass seit dem hinzufügen des Codes bestimmen, ob
mainXMLLoader.bytesLoaded == mainXMLLoader.bytesLoaded
ich habe nicht hatte ein Problem - der hat gesagt, dieser bug ist schwer zu reproduzieren, so dass für alle I weiß, ich habe nicht Feste überhaupt, und stattdessen nur Hinzugefügt nutzlosen code.InformationsquelleAutor Jeff Winkworth
Den
Event.COMPLETE
handler sollte wirklich nicht genannt werden, es sei denn, der Lader war voll beladen, macht es keinen Sinn. Haben Sie bestätigt, dass es in der Tat nicht vollständig geladen (durch einen Blick auf dasbytesLoaded
vs.bytesTotal
Werte, die Sie verfolgen)? Wenn dieEvent.COMPLETE
- Ereignis wird ausgelöst, bevorbytesLoaded == bytesTotal
dass ist ein bug.Gut, dass du Sie hast, arbeiten mit dem timer, aber es ist sehr seltsam, dass Sie es brauchen.
InformationsquelleAutor Theo
Schlage ich vor, dass Sie einen bug-Bericht an https://bugs.adobe.com/flashplayer/, denn die Veranstaltung sollte das wirklich nicht das Feuer, bevor alle bytes geladen sind. In der Zwischenzeit habe ich denke, Sie haben zu Leben mit dem timer. Sie könnten in der Lage sein, dasselbe zu tun, durch das hören auf das progress-Ereignis statt, das könnte vielleicht sparen Sie von dem Griff, den timer selbst.
InformationsquelleAutor Theo
manchmal die RSS-Seite server nicht ausspucken richtige und gültige XML-Daten vor allem, wenn Ihr ständig es zu schlagen, so kann es nicht Ihre Schuld ist. Haben Sie versucht, schlagen Sie die Seite in einem web-browser (vorzugsweise mit einem xml-validator-plugin), um zu überprüfen, dass der server die Antwort ist immer gültig?
Die einzige andere Sache, die ich hier sehen kann, ist die Zeile:
Haben Sie auch versucht, die Einstellung der urlloader-dataFormat auf URLLoaderDataFormat.TEXT, und auch hinzufügen, url, Header, der prama-no-cache und/oder hinzufügen einer cache-buster tot, er url?
Nur ein paar Vorschläge...
InformationsquelleAutor enzuguri
Konnten Sie eine eindeutige element-namespace am Ende Ihrer XML-Dokument, das ein Attribut "Wert" den Wert "true";
Ich hoffe, dass dies hilft Ihnen für jetzt, aber die wirkliche Hoffnung ist, dass genug Leute, damit adobe über dieses Problem erfahren. Es ist eine traurige Sache, nicht verlassen können, um auf Ereignisse. Ich muss aber sagen, von dem, was ich gehört habe, über XML -, ist es nicht sehr optimal, im großen Maßstab und glauben, dass dies ist, wenn Sie so etwas wie AMFPHP zu serialisieren der Daten.
Hoffe, das hilft! Denken Sie daran, die Idee hier ist, dass wir wissen, was das Letzte Kind/element in der XML ist, weil wir es einrichten! Es gibt keinen Grund, dass wir nicht in der Lage sein, um Zugriff auf das Letzte untergeordnete Element/element, aber wenn wir nicht können, müssen wir davon ausgehen, dass die XML wurde zwar nicht abgeschlossen, und wir zwingen es wieder zu laden.
InformationsquelleAutor Brian Hodge