简体   繁体   中英

AS3 - Merging XML Files

I'm creating a trivia game is Flash (AS3) with two different categories. The player can choose one category, or the other, or both categories together. In the code below I'm trying to merge the two xml files together into a new xml file if the person selects both categories. I'm getting an "Access of undefined property error for myLoader and myLoader2 and I don't know why.

// start loading of questions
public function xmlImport() 
{
    var myLoader:URLLoader = new URLLoader();
    var myLoader2:URLLoader = new URLLoader();

    if (so.data.question_set == "BOTH")
    {
        myLoader.load(new URLRequest("category1.xml"));
        myLoader2.load(new URLRequest("category2.xml"));
        myLoader.addEventListener(Event.COMPLETE, loadXML2);

        function loadXML2() 
        {
            myLoader2.addEventListener(Event.COMPLETE, combineXML);
        }
    }

    if (so.data.question_set == "ONE")
    {
        myLoader.load(new URLRequest("category1.xml"));
        myLoader.addEventListener(Event.COMPLETE, xmlLoaded);
    }

    if (so.data.question_set == "TWO")
    {
        myLoader.load(new URLRequest("category2.xml"));
        myLoader.addEventListener(Event.COMPLETE, xmlLoaded);
    }
}

public function combineXML() 
{
    var xmlJoin:XML = <trivia></trivia>;
    var i:XML;

    for each(i in myLoader)
    {
        xmlJoin.appendChild(i);
    }

    for each(i in myLoader2)
    {
        xmlJoin.appendChild(i);
    }

    trace(xmlJoin);
}

Thanks for any help you can offer.

Rich

In the third option could you not have two loaders and when each completes, the result XML is appended to a previously defined empty XML value.

A rough example:

var xml1:XML =
<trivia>
    <question>What is the difference between a duck?</question>
    <answer>I have no idea</answer>
</trivia>;

var xml2:XML =
<trivia>
    <question>2+2</question>
    <answer>4</answer>
</trivia>;


var xmlJoin:XML = <sheet></sheet>;


var i:XML;
for each(i in xml1)
{
    xmlJoin.appendChild(i);
}

for each(i in xml2)
{
    xmlJoin.appendChild(i);
}

trace(xmlJoin);

You can simply use the appendChild() method of an XML object like the following:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite 
    {
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            var xml1:XML = <rootNode>
                               <parentNode>
                                   <childNode>1</childNode>
                                </parentNode>
                            </rootNode>;

            var xml2:XML = <rootNode>
                               <parentNode>
                                   <childNode>2</childNode>
                                </parentNode>
                            </rootNode>;

            xml1.parentNode.appendChild(xml2.parentNode.childNode);

            trace(xml1); // output: <rootNode>
                         //             <parentNode>
                         //                 <childNode>1</childNode>
                         //                 <childNode>2</childNode>
                         //             </parentNode>
                         //         </rootNode>

        }// end function

    }// end class

}// end package

[UPDATE]

You can also simply merge both XML objects into an XMLList object like the following:

var xmlList:XMLList = XMLList(xml1.toString().concat(xml2.toString())); // XMLList(xml1 + xml2)

trace(xmlList); // output: <rootNode>
                //             <parentNode>
                //                 <childNode>1</childNode>
                //             </parentNode>
                //         </rootNode>
                //         <rootNode>
                //             <parentNode>
                //                 <childNode>2</childNode>
                //             </parentNode>
                //         </rootNode>

[UPDATE 2]

I rewrote your application(well the portion of your application you posted) to show you the approach you may want to take:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.SharedObject;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    public class Main extends Sprite 
    {
        private var _sharedObject:SharedObject;
        private var _urls:Array;
        private var _xmls:Vector.<XML>;
        private var _xmlsLoaded:int;

        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            _sharedObject = SharedObject.getLocal("questions");
            _sharedObject.data.category = Category.BOTH;

            _xmls = new Vector.<XML>();

            switch(_sharedObject.data.category)
            {
                case Category.ONE:  loadXml("xml/category1.xml");                      break;
                case Category.TWO:  loadXml("xml/category2.xml");                      break;
                case Category.BOTH: loadXml("xml/category1.xml", "xml/category2.xml"); break;

            }// end switch

        }// end function

        private function loadXml(...urls):void
        {
            _urls = urls;

            for each(var url:String in urls)
            {
                var urlLoader:URLLoader = new URLLoader(new URLRequest(url));
                urlLoader.addEventListener(Event.COMPLETE, onUrlLoaderComplete);

            }// end function

        }// end function

        private function onUrlLoaderComplete(e:Event):void
        {
            _xmls.push(XML(URLLoader(e.target).data));

            if (_urls.length == ++_xmlsLoaded) traceXMLList();

        }// end if

        private function traceXMLList():void
        {
            trace(getXMLList(_xmls)); // output: <category1>
                                      //             <question>question 1</question>
                                      //             <question>question 2</question>
                                      //         </category1>
                                      //         <category2>
                                      //             <question>question 1</question>
                                      //             <question>question 2</question>
                                      //         </category2>


        }// end function

        private function getXMLList(_xmls:Vector.<XML>):XMLList
        {
            var xmlList:XMLList = new XMLList();

            for (var i:uint = 0; i < _xmls.length; i++)
            xmlList += _xmls[i];

            return xmlList;

        }// end function

    }// end class

}// end package

internal class Category
{
    public static const ONE:String = "one";
    public static const TWO:String = "two";
    public static const BOTH:String = "both";

}// end class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM