tutorials.de Buch-Aktion 05/2012
RSS-Feed anzeigen

luke_the_duke's Blog

AS 2.0: XMLObject-Klasse

Bewerten
von luke_the_duke am 27.04.07 um 14:22 (148 Hits)
Mit der XMLObject-Klasse lassen sich XML-Dateien laden. Im Unterschied zur XML-Klasse wird das Ergebnis jedoch gleich in eine Objekt-Struktur umgewandelt, so dass man statt mit ewigen childNodes[xy]-Ketten simpel mit den Tag- und Attributnamen auf einen Knoten, einen Wert oder ein Attribut zugreifen kann.
Die Klasse:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class XMLObject {
    //Native onLoad
    public var onLoad: Function;
    
    //Loader Objects
    private var xml: XML;
    private var lv: LoadVars;
    
    //Constructor
    function XMLObject () {
        mx.events.EventDispatcher.initialize(this);
        addEventListener ("onLoad", this);
    }
    
    //Dispatcher Functions
    function dispatchEvent() {};
    function addEventListener() {};
    function removeEventListener() {};
    
    //Broadcaster Function
    private function broadcastMessage(obj: Object, en: String): Void {
        obj.target = this;
        obj.type = en;
        dispatchEvent(obj);
    }
    
    //Adds Event-Listener
    public function addListener (obj): Void {
        addEventListener("onLoad", obj);
    }
    
    //Removes Event-Listener
    public function removeListener (obj): Void {
        removeEventListener("onLoad", obj);
    }
    
    //Load Funtion
    public function load (data: LoadVars, Url: String, Method: String, showSource: Boolean): Void {
        
        var p: XMLObject = this;
        
        xml = new XML();
        xml.ignoreWhite = true;
        
        lv = new LoadVars ();
        lv = data;
        
        xml.onLoad = function () {
            
            if (showSource) trace (this);
            
            var obj: Object = p.getObj(this.firstChild);
            p.broadcastMessage(obj, "onLoad");
        }
        
        lv.sendAndLoad(Url, xml, Method);
    }
    
    //Converts Node to Object, calls itself if node has Children
    private function nodeToObject (obj: Object, n: XMLNode): Void {
    
        var e: Number = n.childNodes.length;
        var l: Number = e;
        
        while (l--) {
            
            var node: XMLNode = n.childNodes[l];
            var id: String = node.nodeName;
            
            if (node.hasChildNodes()) {
                                
                var str: String = (obj[id]) ? id+"_"+(e-l): id;
                
                obj[str] = {};
                nodeToObject (obj[str], node);
                
                for (var i: String in node.attributes) obj[str][i] = (typeof(node.attributes[i]) == "number") ? Number (node.attributes[i]): String (node.attributes[i]);
 
            } else if (node.nodeValue != null) obj.value = (typeof(node.nodeValue) == "number" || !isNaN(Number(node.nodeValue))) ? Number (node.nodeValue): String (node.nodeValue);
        }
    }
    
    //Starts convertion
    private function getObj (node: XMLNode): Object {
        
        var obj: Object = {};
        
        nodeToObject(obj, node);
        
        return obj;
    }
}

Konstruktor:
Code :
1
var xmObject = new XMLObject();

Methoden:

load (Data: LoadVars, Url: String, Method: String, showSource: Boolean): Void


Diese Funktion lädt eine XML-Datei in die Instanz der XMLObject-Klasse.

Parameter:
Data: Ein LoadVars-Objekt, in dem alle benötigten Parameter gespeichert sind.
Url: String, URL der XML-Datei.
Method: Methode, mit der die Lade-Aktion durchgeführt wird ("GET" oder "POST").
showSource: Optional. Wenn showSource auf true gesetzt wird, printet das XMLObject die ursprünglich geparste XML-Datei ins Ausgabe-Fenster.

addListener (ZielObjekt: Object): Void

Mit diese Methode können weitere Objekte als Event-Listener des enstprechenden XMLObjects registriert werden.

Parameter:
ZielObjekt: Object. Ein Listener-Objekt, auf dem die Event-Methoden des XMLObjects aufgerufen werden

removeListener (ZielObjekt: Object): Void
Mit dieser Methode wird ein Objekt aus der Liste der Listener entfernt.

Parameter:

ZielObjekt: Object. Name des Objekts, das ausgetragen werden soll.


Ereignisse:

onLoad = function (dataObject: Object)


Wird aufgerufen, wenn die XML-Datei komplett geladen, geparst und umgewandelt ist

Parameter:
dataObject: Object, das die umgewandelte XML-Struktur beinhaltet

Ich habe bei der Programmation ein paar Konventionen festlegen müssen, ich erkläre das Teil und seine Macken am besten an einem Beispiel. Folgendes XML-Dokument wollen wir in Flash umsetzen:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<xm>
    <person id="1">
        <vorname>Hans</vorname>
        <name>Muster</name>
        <beruf>Informatiker</beruf>
    </person>
    <person id="2">
        <vorname>Veronica</vorname>
        <name>Beispiel</name>
        <beruf>Floristin</beruf>
    </person>
    <person id="3">
        <vorname>Hermann</vorname>
        <name>Vorlage</name>
        <beruf>Sachbearbeiter</beruf>
    </person>
</xm>

Nun erstellen wir ein XMLObject mit einem Lade-Aufruf inkl. LoadVars und Parameter und einer onLoad-Funktion:

Code :
1
2
3
4
5
6
7
8
9
10
var xmlData: XMLObject = new XMLObject();
xmlData.onLoad = function (obj: Object) {
    for (var i: String in obj) trace (i+": "+obj[i]);
}
 
 
var lv: LoadVars = new LoadVars();
lv.id = "5";
 
xmlData.load(lv, "meineXMLDatei.xml", "GET", true);

Konvention 1:
Jede XML-Datei, die mit dem XMLObject geparst werden will, muss über einen Mutterknoten verfügen, der über allen anderen Knoten steht. In unserem Beispiel wäre das nun der xm-Knoten.

Die Ausgabe dieses Codes sollte etwa so aussehen:
Code :
1
2
3
person: Object
person_2: Object
person_3: Object

Und hier wird schon Konvention 2 ersichtlich:
Verfügt ein Knoten über mehrere Kindknoten gleichen Namens, wird das erste Kind-Objekt wie der Tagname getauft, alle folgenden jedoch mit einem Affix versehen, dass sich aus einem Tiefstrich und einer fortlaufend inkrementierten Zahl zusammensetzt.

Spielen wir das Beispiel mit einer etwas modifizierten onLoad-Ausgabe durch:
Code :
1
2
3
xmlData.onLoad = function (obj: Object) {
    for (var i: String in obj.person) trace (i+": "+obj.person[i]);
}

Diese Ausgabe sieht nun so aus:
Code :
1
2
3
4
vorname: Object
name: Object
beruf: Object
id: 1

Da in jedem Person-Knoten jeder Tagname nur einmal vorkommt, wird auch kein Objekt mit einem Affix versehen.

Und nun kommen wir zur dritten und vierten Konvention:
Attribute werden wie auch Kindknoten direkt als Member des Mutterknotens eingetragen und mit dem entsprechenden Wert belegt.

Der Inhalt von Knotenpunkten, die über einen Text als Kindknoten verfügen, also das letzte Glied in der Reihe sind, kann dieser Text über das Member-Objekt value aufgerufen werden. Das mag ein wenig unschön erscheinen, ist aber unumgänglich (man belehre mich eines Besseren), da bei der Diagnose auch ein Textknoten als Kindknoten gewertet wird.

Mit folgender letzter onLoad-Funktion referenziere ich abssolut drei verschiedene Werte:
- Das id-Attribut des ersten person-Knotens
- Den Beruf des zweiten person-Knotens
- Den Vor- und Nachnamen des dritten Knotens

Code :
1
2
3
4
5
xmlData.onLoad = function (obj: Object) {
    trace (obj.person.id);
    trace (obj.person_2.beruf.value);
    trace (obj..person_3.vorname.value+" "+obj.person_3.name.value);
}

Auf das die Klasse eure Arbeit mit XML und Flash erleichtern möge .

VIel Spass!

"AS 2.0: XMLObject-Klasse" bei Twitter speichern "AS 2.0: XMLObject-Klasse" bei Facebook speichern

Kategorien
Webmaster

Kommentare