XML - targeting node attribute, push into a Flash AS3 array

♀尐吖头ヾ 提交于 2019-12-25 06:36:13

问题


I'm trying to push just the contents of the "txt" attribute in each "question" tag into an array named "questions" in AS3 Flash. Here is an excerpt from my xml file.

<question id='Q1' uId='99036'  no_ans='2' txt='In a flat structure employees are not expected to provide their bosses with their opinions.' feedback='' type='MC' passingWeight='1' url='media/'>
    <answer id='Q1A1' uId='311288' txt='True' weight='0'/>
    <answer id='Q1A2' uId='311289' txt='False' weight='1'/>
</question>
<question id='Q2' uId='99037'  no_ans='2' txt='In a hierarchy, information typically flows downward.' feedback='' type='MC' passingWeight='1' url='media/'>
    <answer id='Q2A1' uId='311290' txt='True' weight='1'/>
    <answer id='Q2A2' uId='311291' txt='False' weight='0'/>
</question>
<question id='Q3' uId='99038'  no_ans='2' txt='Someone who keeps many projects going at one time is an example of someone who is flexible-time oriented.' feedback='' type='MC' passingWeight='1' url='media/'>
    <answer id='Q3A1' uId='311292' txt='True' weight='1'/>
    <answer id='Q3A2' uId='311293' txt='False' weight='0'/>
</question>

Here is my attempt at a loop:

// get number of questions
    trace(myXML.question.length());
    numberOfQuestions = myXML.question.length();

    //loop and push questions into questions array at top
    for (var i:int = 0; i < numberOfQuestions; i++) {
        trace("Hello.");
        questions.push(myXML.question.@txt);
        trace(questions);
    }

This just pushes all 9 of the questions at once into each position of the array. I wanted 1 question per array position. I'm not sure how to use the id attribute in the question tag to differentiate each question.

EDIT: I tried this and I can access the questions texts using getQuestionAt(2) from within the processXML function, but not outside of it.

var myXML:XML;
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("html/VUBZ7318CROSSCULTUREQUIZ/manifest.xml"));
myLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void {
    myXML = new XML(e.target.data);

    //trace(myXML.question)

    // get number of questions
    trace(myXML.question.length());
    numberOfQuestions = myXML.question.length();

    //Question list
    var questions:Object = {};
    //Extracting question from xml
    for each (var item:XML in myXML.question) {
        questions[item. @ id] = item. @ txt;
    }
    //Some method for fetching question from question list
    function getQuestionAt( index:Number ):String {
        if (questions["Q" + index] == undefined) {
            throw new Error("Wrong index for question!!!");
        }
        return questions["Q"+index];
    }

    //Getting question from list
    trace( "Here is question No 2:\t" + getQuestionAt(2) );


}

回答1:


Create new layer, which have only one frame, and make that frame's length as long as your total frames are(for instance 6 as long). Then put this code in that frame.

//Question list
var questions:Object; 
//Some method for fetching question from question list
function getQuestionAt( index:Number ):String{
    if( questions["Q"+index] == undefined ){
        throw new Error("Wrong index for question!!!");
    }
    return questions["Q"+index];
}    

Then add these lines into your processXML function

function processXML():*{
 //.....Your 'myXML' is here....
 questions = {};
 //Extracting question from xml
 for each(var item:XML in myXML.question){
    questions[item.@id] = item.@txt;
 }
}   

Call getQuestionAt whenever you want to get questions. You can call that function in any frame, because it's 'visible' on all frames.




回答2:


You XML is set up just a tad wrong. In AS3 you need a root node. A root node is not accessible it's just kind of a wrapper. In your case Question is your root node which is not accessible, which will make those attributes not accessible also. So put a wrapper around your xml. I could be wrong about not being able to access the root node attributes however I am correct on your XML not being proper. And adding the wrapper just makes like easier.

<questions>
  <question id='Q1' uId='99036'  no_ans='2' txt='In a flat structure employees are not expected to provide their bosses with their opinions.' feedback='' type='MC' passingWeight='1' url='media/'>
      <answer id='Q1A1' uId='311288' txt='True' weight='0'/>
      <answer id='Q1A2' uId='311289' txt='False' weight='1'/>
  </question>
  <question id='Q2' uId='99037'  no_ans='2' txt='In a hierarchy, information typically flows downward.' feedback='' type='MC' passingWeight='1' url='media/'>
      <answer id='Q2A1' uId='311290' txt='True' weight='1'/>
      <answer id='Q2A2' uId='311291' txt='False' weight='0'/>
  </question>
  <question id='Q3' uId='99038'  no_ans='2' txt='Someone who keeps many projects going at one time is an example of someone who is flexible-time oriented.' feedback='' type='MC' passingWeight='1' url='media/'>
      <answer id='Q3A1' uId='311292' txt='True' weight='1'/>
      <answer id='Q3A2' uId='311293' txt='False' weight='0'/>
  </question>
</questions>

And then grab the attribute like so.

var questions:XMLList =  new XMLList( e.target.data.question )
for each ( var question:XML in questions){
  trace( question.@txt )
}



回答3:


What you have is not XML, but an XMLList, and it is perfectly acceptable.

You don't need to loop through. You can get another XMLList like this. An XMLList is like an array of XML, but in this case you won't have fully formed nodes, but just the contents of all the attributes.

It will go something like this:

var questionTxt:XMLList = yourQuestions.@txt;//yourQuestions contains your originalXMLList as shown above

Now, you can access each text element as:

var stem:String = String(questionTxt[0]);

If for some reason you absolutely must have an Array, you can do this:

var questions:Array = new Array();
for (var i:int = 0; i< questionTxt.length(); i++) {
    questions[i] = questionTxt[i];
}

However, it looks like a lot of work for nothing, since you can simply use the XMLList as it is by accessing it with e4x. What is your full goal?

I just looked at your question a bit more carefully, and all you really need to do is this:

protected var questions:XMLList;
public function processXML(e:Event):void {
            myXML = XML(e.target.data);
            questions = myXML.question;

            // get number of questions
            trace(myXML.question.length());
}

public function getQuestionAt( index:Number ):String {
            if (questions[index] == undefined) {
                throw new Error("Wrong index for question!!!");
            }
            return questions[index].attribute('txt');
}       

public function get numberOfQuestions():int {
    return myXML.question.length();
}


来源:https://stackoverflow.com/questions/9727946/xml-targeting-node-attribute-push-into-a-flash-as3-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!