2009-03-07 1 views
2

Ich kann nicht umhin zu denken, dass XML-Anzeige XMLList beide nicht verwandt sind, da sowohl Objekt direkt erweitern, ist ein Konstruktionsfehler in der AS3-Core-Bibliothek. Mit XML extend XMLList wäre ein viel saubereres System, in dem XML als XMLList mit nur einem Mitglied betrachtet wird?Warum sind in AS3 XML- und XMList-Klassen ohne Bezug zueinander (erben)?

Dies würde auch die sehr lästige Praxis einer E4X-Abfrage vermeiden, die möglicherweise entweder eine XML- oder XML-Liste zurückgibt, was zu einem Casting-Fehler führen kann.

Gibt es irgendeinen Grund, warum ich nicht daran denke, dass XML und XMLList so entworfen wurden, dass sie nur Objekt als einen gemeinsamen Typ haben?

Antwort

0

Also meine kurze Antwort auf diese Frage ist, dass, wie es scheint, aus der Betrachtung des Vererbungsbaum, der ja die beiden Klassen (XMLList, XML) nicht verwandt sind.

Aber aus der ECMA-Skript/AS3-Dokumentation, dass sie verwandt sind, am wahrscheinlichsten mit dem Prototyp-System von ECMA-Skript/AS3.

Wenn eine XMLList nur ein Mitglied hat, kann sie wie ein XML-Knoten behandelt werden. Ich gehe davon aus, dass die Methoden und Felder der XML-Klasse vom AVM2 in den XMLList-Prototyp eingefügt werden.

2

Es scheint, dass nach dem ECMA spec for E4X (p22) und die XMLList documentation, dass die XMLList Klasse hat die Methoden der XML Klasse enthält, aber nur, wenn es ein Mitglied. Beim Ausführen einer E4X-Abfrage sollte das Ergebnis daher immer in einer Variablen vom Typ XMLList gespeichert werden.

Zuvor aufgrund der Namensgebung dieser Objekte, I angenommen, dass ein XML Objekt einen komplexen Baum von XML-Element-Daten dargestellt, aber entsprechend den spec (P12), ist dies nicht wahr „Jeder Wert vom Typ XML stellt ein XML-Element, Attribut, Kommentar, Verarbeitungsanweisung oder Textknoten dar ".

Es ist die XMLList Klasse, die als generischer Typ des beide verwendet werden soll: „Ein Wert vom Typ XMLList stellt ein XML-Dokument, XML-Fragment oder eine beliebige Sammlung von XML-Objekten (zB ein Abfrageergebnis) "

Das löst also mein Casting-Problem, da ich E4X-Abfragen niemals als Variable vom Typ XML gespeichert haben sollte. Ich sollte nur die Klasse XML für das Iterieren über XMLLists und das Auseinanderbrechen von XML-Elementen verwenden.

0

Wie Sie bemerkt haben, kann die automatische Änderung von XML- und XMLList-Typen ziemlich verwirrend sein. Solche Dinge passieren, wenn clevere Programmierer (die hier auf Adobe verweisen ...) Convenience Wrapper um Dinge herum machen.

Was passiert ist eine Art "automatische Typumwandlung". Und es hört nicht auf den XML-Typ auf. Betrachten Sie dieses Beispiel XML:

<myXml> 
    <sound id="0">Boogaloo</sound> 
    <sound id="1">Bond theme</sound> 
    <sound id="2">2001</sound> 
</myXml> 

Lassen Sie uns sagen, ich habe die oben XML in einer Variablen myXml genannt.Im folgenden Beispiel werden die E4X ein XMLList mit einem Element, und wir Zugriff auf das erste XML-Element mit [0]:

trace(myXml.sound.(@id == 0)[0] == <sound id="0">Boogaloo</sound>); 
// traces true 

In diesem Beispiel auslassen wir den [0] Teil, auf dem das automatische Umwandeln von Flash zu verlassen. Das eine Element zurückgegeben wird in XML konvertiert:

trace(myXml.sound.(@id == 0) == <sound id="0">Boogaloo</sound>); 
// traces true 

Aber in Fällen, in denen dies ein XML-Knoten angepasst enthält einen einfachen Textknoten konvertiert Flash automatisch die Art noch weiter in einen String:

trace(myXml.sound.(@id == 0) == "Boogaloo"); 
// traces true 

Und Wenn der Textknoten als Zahl interpretiert werden kann (XML-Knoten mit der ID 2), konvertiert Flash ihn sogar weiter in eine Zahl!

trace(myXml.sound.(@id == 2) == 2001); 
// traces true 

Woot!

Also, was ist damit zu tun?

Wie Sie bemerkt haben, müssen Sie sehr vorsichtig mit Typen und der "praktischen" XML-Handhabung sein. Eine vorgeschlagene Praxis ist es, immer den Array-Zugriffsoperator zu verwenden, um den ersten XML-Element eines E4X Ergebnis zu zeigen, wenn Sie wissen, dass Sie ein einzelnes Ergebnis wollen:

config.users.admin[0].settings[0].email.(@type == "work")[0]; 

Es sieht auf den ersten seltsam, und fügt Ausführlichkeit die Code, aber der Vorteil ist, dass Sie explizit da sagen, dass Sie sich für einadmin Element, einsettings Element und einemail Elemente vom Typ "work" suchen. Und du gewöhnst dich daran.

Ein weiterer Tipp ist, sich immer an den Typ zu erinnern, den Sie verwenden möchten. Einige Beispiele:

allUsers  = XMLList(config.users); 
adminSettings = XML(config.users.admin[0].settings[0]); 
adminWorkEmail = String(config.users.admin[0].settings[0].email.(@type == "work")[0]); 
adminBirthYear = int(config.users.admin[0].birthdate[0][email protected][0]); 
0

In Actionscript 3.0 XMLList die neue Art und Weise ist xml zu behandeln, in denen wie die XML-Klasse ist eine AS 2 Sache so war es gehört zu bieten Abwärtskompatibilität.

Wenn Sie neuen Code schreiben, sollten Sie jetzt die XMLList verwenden.

hoffe, das hilft

Jon

+0

Hey Jon, ich habe keine Verwirrung über die XML-Klasse von AS2 übernommen, Die Verwirrung war, dass es ein XMLList und und XML-Klasse in AS3 Kern lib vorhanden ist. Die Beziehung zwischen diesen war für mich verwirrend. Ich sehe das als einen Fall von schlechter Benennung, Sie können meine Antwort oben sehen –