views:

641

answers:

3

Hello, I am trying to load data from an XML file into a flash object. When making the flash object in actionscript it looks like this:

var presentationObj:Object = {
casestudies: {
 audi: {
  titleStr: 'Audi',
  placement: 'study',
  slides:{
  1:{ src:'img/page1.jpg', group:'img' },
  2:{ src:'img/page2.jpg', group:'img' }
  }
 }
}

and that works. I am trying to get the XML to be loaded into the flash object using the same format (so I can keep the rest of the code I am already using). I have no idea how to go about doing this though. Any ideas?

A: 

XML has other object semantics than ECMAscript ... so this is always a little unpleasant ... you should consider using JSON instead of XML ... it's also standardized, it is smaller, treats numeric and boolean values as such and has a few other advantages ... but most importantly, semantics are the same ...

a problem with XML is, that { foo: "bar" } could be <node foo="bar" /> or <node><foo>bar</foo></node> ... plus it is unclear, where the name of node should come from ... etc. ... it is very often unclear, what a sensible and unique XML-representation of an object is, or how an XML should be translated into an object tree ...

for simple and elegant XML manipulation in AS3, have a look at E4X

but really, i'd use JSON (use as3corelib for en-/decoding) ...

hope that helps ... :)

back2dos
+1  A: 

Check out the AS3 docs on the classes XML and XMLNode. You can probably implement a simple loader (depending on what your XML schema looks like, if you have one yet) by looping through the levels of the node tree by hand and loading node contents and attributes as needed.

Edit: Found my XML to object parsing code:

public function xml2Object(baseNode:XMLNode):Object {
 var xmlObject:Object = new Object;

 // attributes
 var attribs:Object;
 for (var attribName:String in baseNode.attributes) {
  if (attribs == null)
   attribs = new Object;

  attribs[attribName] = parseXMLValue(baseNode.attributes[attribName]);
 }
 if (attribs != null)
  xmlObject["_attrib"] = attribs;

 // children
 for (var childNode:XMLNode = baseNode.firstChild; childNode != null; childNode = childNode.nextSibling) {
  // if its a text node, store it and skip element parsing
  if (childNode.nodeType == 3) {
   xmlObject["_text"] = parseXMLValue(childNode.nodeValue);
   continue;
  }

  // only care about elements from here on
  if (childNode.nodeType != 1)
   continue;

  // parse child element
  var childObject:Object = xml2Object(childNode);

  // no child exists with node's name yet
  if (xmlObject[childNode.nodeName] == null)
   xmlObject[childNode.nodeName] = childObject;
  else {
   // child with same name already exists, lets convert it to an array or push on the back if it already is one
   if (!(xmlObject[childNode.nodeName] instanceof Array)) {
    var existingObject:Object = xmlObject[childNode.nodeName];
    xmlObject[childNode.nodeName] = new Array();
    xmlObject[childNode.nodeName].push(existingObject);
   }
   xmlObject[childNode.nodeName].push(childObject);
  }
 }

 return xmlObject;
}

public function parseXMLValue(value:String):Object {
 if (parseFloat(value).toString() == value)
  return parseFloat(value);
 else if (value == "false")
  return false;
 else if (value == "true")
  return true;
 return value;
}

xml2Object will turn:

<some_object>
 <sub_object someAttrib="example" />
 <sub_object anotherAttrib="1">
  <another_tag />
  <tag_with_text>hello world</tag_with_text>
 </sub_object>
 <foo>bar</bar>
</some_object>

into:

{
 some_object:
 {
  sub_object:
  [
   {
    _attrib:
    {
     someAttrib: "example"
    }
   },
   {
    tag_with_text:
    {
     _text: "hello world"
    },
    another_tag:
    {
    },
    _attrib:
    {
     anotherAttrib: 1
    }
   }
  ],
  foo:
  {
   _text: "bar"
  }
 }
}
nikaji
A: 

Try this. Note that all keys and values end up as strings.

Given the following XML:
<test id="an ID"> <subnode> <subsubnode> Cheese </subsubnode> </subnode> </test>
It should generate the following object:
{ id: "an ID", subnode: { subsubnode: "Cheese" } }

Disclaimer: Not thoroughly tested!

function objectFromXML(xml:XML):Object
{
 var obj:Object = {  };

           // Check if xml has no child nodes:
 if (xml.hasSimpleContent()) {
  return String(xml);     // Return its value
 }

 // Parse out attributes:
 for each (var attr:XML in xml.@ * ) {
  obj[String(attr.name())] = attr;
 }

 // Parse out nodes:
 for each (var node:XML in xml.*) {
  obj[String(node.localName())] = objectFromXML(node);
 }

 return obj;
}
Cameron