this._validParseKids.kml = { Document : { func: this.parseXML } , Folder : { func : this.parseFolder } , Placemark : { func : this.parsePlacemark } }; this._validParseKids.Document = { Folder : { func : this.parseFolder } , Placemark : { func : this.parsePlacemark } , Style: { func : this.parseStyle } , StyleMap: { func : this.parseStyleMap } }; this._validParseKids.Folder = { Folder : { func : this.parseFolder } , Placemark : { func : this.parsePlacemark } };
As you can see the kml object has three possible children: Document, Folder, and Placemark. Each of these have a func(Function) assigned to them. So if we are in the kml tag and find a Document the this.parseXML function will be executed. This parseXML function looks like this:
protected function parseXML( x:XML ) : Object { var returnObject:Object = new Object(); var validKids:Object = this._validParseKids[x.name().localName]; if( validKids != null ){ var kids:XMLList = x.children() for each( var node:XML in kids ){ var validKid:Object = validKids[node.name().localName]; if( validKid != null && validKid.func is Function ){ validKid.attrName = ( validKid.attrName == null ) ? node.name().localName : validKid.attrName; if( validKid.attrType == "Array" ){ if( returnObject[validKid.attrName] is Array == false ){ returnObject[validKid.attrName] = new Array(); } returnObject[validKid.attrName].push( validKid.func( node ) ); } else{ returnObject[validKid.attrName] = validKid.func( node ); } } } } else{ returnObject = "Not Found in Valid Kids Object"; } return returnObject; }
If you notice there are two other variables in the this._validParseKids object, attrName and attrType. Here is an example of both:
this._validParseKids.Placemark = { Point : { attrName: "_shape" , func : this.parsePoint} , LineString : { attrName: "_shape" , func : this.parseLineString } , LinearRing : { attrName: "_shape" , func : this.parseLinearRing } , Polygon : { attrName: "_shape" , func : this.parsePolygon } , name : { attrName: "name" , func : this.parseString } , address : { attrName: "address" , func : this.parseString } , phoneNumber : { attrName: "phoneNumber", func : this.parseString } , Snippet : { attrName: "Snippet" , func : this.parseString } , description : { attrName: "description", func : this.parseString } , styleUrl : { attrName: "_style" , func : this.parseStyleUrl } , ExtendedData : { attrName: "_data" , func : this.parseExtendedData } }; this._validParseKids.ExtendedData = { Data : { attrName : "kvPairs" , attrType : "Array" , func : this.parseData } };
So the attrName is the name of the object that any returned values from the function that was called may return. The attrType is only used to say that there will be multiple objects that return data to the given attrName. So for example the when in the ExtendedData tag you can have an unlimited number of Data tags that are to be stored in an array. As a final example here are a couple of the basic parse functions:
protected function parseString( text:XML ) : String { return text.toString(); } protected function parseInt( i:XML ) : int { var s:String = i.toString(); var n:Number = Number( s ); if( isNaN( n ) ){ n = this.stringToHex( s ); } return int( n ); } protected function parseNumber( n:XML ) : Number { return Number( n.toString() ); } protected function parseBoolean( b:XML ) : Boolean { var value:String = b.toString(); if( value.match( /(1|true)/ ) ){ return true; } return false; }