问题
I am trying to update an xml file and save elements inside of an already saved root element.
I have only found examples where the xml files are just opened and not saved. Can someone help me to find the best way to save the results?
My project right now looks like this:
I am loading an xml file via URLLoader/URLRequest and display the contents in several text fields. New text from an input field is saved (appended) via FileStream directly to the xml file in the applicationStorageDirectory (that will be on iPhone).
The new input should then be added to an on-screen list (created with a for-loop) and displayed, however, it can't get it that far. After reading the newly saved input from the xml file, I naturally get error 1088 because the xml file is not well-formed anymore.
This is because the input is appended after the root element and the result looks like this:
<root>
<message></message>
<date></date>
</root>
<message>new input</message>
<date></date>
When of course what I want is this:
<root>
<message></message>
<date></date>
<message>new input</message>
<date></date>
</root>
But I have no idea how i can achieve that.
I made several attempts to avoid having to append, like loading the xml content, changing it, and then writing everything again. But since I am still new to as3 I couldn't get it to work.
It would be great if someone could tell me what the best way to go would be and maybe how to solve it.
回答1:
Alright just figured I'd post an update on where I'm at so far...
This should be able to output XML for most objects, I just threw a few test cases at it so far if you'd like to start trying to debug with this and let me know if you have any parts missing or bad XML output let me know... I'm going to continue and try and work on a parser to reverse the process the XML generated by this version may change when I do that.
package
{
import flash.utils.describeType;
import mx.collections.IList;
public class AS3ToXMLMapper
{
public function AS3ToXMLMapper()
{
}
public static function generateXML(objectToMap:Object, basePropertyName:String="root"):String
{
var describeXML:XML = describeType(objectToMap);
var xmlOutput:String = "<"+basePropertyName+" name=\""+describeXML.@name+"\" base=\""+describeXML.@base+"\">\n";
if(describeXML.@isDynamic=="true")
{
for(var property:String in objectToMap)
{
xmlOutput += "<"+property+">";
xmlOutput += objectToMap[property];
xmlOutput += "</"+property+">";
}
}
else if(objectToMap is XML)
{
xmlOutput+=(objectToMap as XML).toString();
}
else if(objectToMap is XMLList)
{
xmlOutput+=(objectToMap as XMLList).toString();
}
else
{
for each(var accessor:XML in describeXML..accessor)
{
xmlOutput+="\t"+exportProperty(objectToMap, accessor,true);
}
for each(var variable:XML in describeXML..variable)
{
xmlOutput+="\t"+exportProperty(objectToMap, variable, false);
}
}
xmlOutput += "</"+basePropertyName+">\n";
trace(xmlOutput);
return xmlOutput;
}
private static function exportProperty(objectToMap:Object, xmlObj:XML, isAccessor:Boolean):String
{
var xmlOutput:String="";
var propName:String = xmlObj.@name.toString();
var objectValue:Object = objectToMap[propName];
if(!objectValue)
{
xmlOutput += "<"+propName+">";
xmlOutput += "</"+propName+">";
return xmlOutput;
}
if(isAccessor && xmlObj.@access != "readwrite")
{
return "";
}
if(objectValue is Array)
{
return exportArray(objectValue as Array, xmlObj.@name);
}
else if(objectValue is IList)
{
return exportArray((objectValue as IList).toArray(), propName);
}
else if(objectValue is int || objectValue is Number || objectValue is String || objectValue is uint || objectValue is Boolean)
{
xmlOutput += "<"+propName+" type=\""+xmlObj.@type+"\">";
xmlOutput += objectValue;
xmlOutput += "</"+propName+">";
}
else
{
return generateXML(objectValue, propName);
}
return xmlOutput;
}
private static function exportArray(array:Array, arrayName:String):String
{
var xmlOutput:String = "<"+arrayName+">\n";
for each(var element:Object in array)
{
xmlOutput+="\t"+generateXML(element,"arrayElement");
}
xmlOutput += "</"+arrayName+">\n";
return xmlOutput;
}
}
}
Usage would be like:
var fs:FileStream = new FileStream();
fs.open(new File("C:\\test.xml"),FileMode.WRITE);
var thingToExport:Object = {aProperty:"someValue"};
var as3XMLMapper:String = AS3ToXMLMapper.generateXML(thingToExport);
fs.writeUTFBytes(as3XMLMapper);
fs.close();
回答2:
Wouldn't it be better to simply work with XML literals?
package
{
import flash.display.Sprite;
public class ZutAlors extends Sprite
{
public function ZutAlors()
{
trace(messagesToXMLString('hello world'.split(' ')));
}
private function messageToXML(m:String, d:Date = null):XMLList
{
return <ret>
<message>{m}</message>
<date>{(d || new Date()).toString()}</date>
</ret>.children();
}
private function messagesToXMLString(array:Array):XML
{
const ret:XML = <root />
for each(var s:String in array)
{
ret.appendChild(messageToXML(s));
}
return ret;
}
}
}
You get a compile error if the XML was not wellformed ...
来源:https://stackoverflow.com/questions/11058721/write-update-and-save-a-well-formed-xml-file-in-as3