-1

If anyone can offer an explanation for this one, I'd LOVE to see it! I was required to append a legacy application to display 20 random questions from an XML data source, as opposed to the total of 70 questions that are part of the original XML. No big deal, right? WRONG! I got it to work just fine in the end, but it's a total HACK! For some reason, some of the nodes that I am appending to a dynamically generated XML document are being returned as "undefined". I kept getting between 16 and 20 questions to render until I modified my iteration from a 'for' loop to a 'do while' loop with the appropriate number of XMLNodes as the condition of the 'do while' loop. Can anyone offer an explanation? Below is the code, with some notes for the reader :

function editXML(xml:XML):XML {

var node:XMLNode = xml.firstChild;
var newNode:XMLNode = new XMLNode();
var nodeArray:Array = new Array();
var usedNodes:Array = new Array();
var totalNodes:Number = node.lastChild.childNodes.length - 1; 
var nextNode:Number;
var returnNode:XMLNode = new XMLNode();
var tempNode:XMLNode;
var buildNode:XMLNode;
var addNode:Boolean = true;

var tempXML:XML = new XML();
var pagesNode:XMLNode = tempXML.createElement("pages");
tempXML.appendChild(pagesNode);
tempXML.appendChild(node.childNodes[0]);
tempXML.appendChild(node.childNodes[1]);
tempXML.appendChild(node.childNodes[2]);
var questionsNode:XMLNode = tempXML.createElement("pages");
tempXML.firstChild.appendChild(questionsNode);
do
{


    nextNode = Math.floor(Math.random()*totalNodes); 
             **//random number to represent random node**
    //trace(nextNode + " nextNode");
    **//check usedNodes Array to look for node.childNodes[nextNode]. If it already exists, skip and reloop.**
    trace(node.childNodes[1].childNodes[nextNode] + " : pre building Node " + totalNodes);
    if(usedNodes.length == 0)
    {
        buildNode = new XMLNode();
        buildNode.nodeName = node.childNodes[1].childNodes[nextNode].nodeName;
                                       buildNode.nodeValue = node.childNodes[1].childNodes[nextNode].nodeValue;
        tempXML.firstChild.lastChild.appendChild(node.childNodes[1].childNodes[nextNode])
        usedNodes.push(node.childNodes[1].childNodes[nextNode]);
        nodeArray.push(node.childNodes[1].childNodes[nextNode]);
        trace("adding first node : " + nodeArray.length); 
        addNode = false;
    }
    else
    {
       for(var j:Number = 0; j < usedNodes.length; j++)
       {
           if(usedNodes[j] == node.childNodes[1].childNodes[nextNode])
           {                
               addNode = false;
               trace("skipping node : " + nodeArray.length);
           }
       }
    }
    **//if node not in usedNodes, add node to XML**
    if(addNode)
    {           


        trace(node.childNodes[1].childNodes[nextNode] + " : building Node"); **//This trace statement produced a valid node**
        tempXML.firstChild.lastChild.appendChild(node.childNodes[1].childNodes[nextNode]);
      **//Before modifying the code from adding nodes to the xml from an Array called 'nodeArray' in a for loop to adding nodes directly to the xml in a do while loop with the length of the xml node used to retrieve data for the questions as the condition, I was not always getting 20 questions. Some of the nodes were being rendered as 'undefined' and not appended to the xml, even though they were traced and proven valid before the attemp to append them to the xml was made**
        usedNodes.push(node.childNodes[1].childNodes[nextNode]);            
  }

    addNode = true;
}
while(tempXML.firstChild.lastChild.childNodes.length <= 19);
trace(tempXML.firstChild.lastChild.childNodes.length + " final nodes Length");

courseXML = tempXML;
//removes the old question list of 70 and replaces it with the new question list of 20. Question list is the last node.


return tempXML;

}

If I had my choice, I would have rebuilt the whole application in Flex with AS3. I didn't have that choice. If anyone can explain this mystery, PLEASE DO! Thank you in advance!

4

1 回答 1

0

我不太明白最初的问题是什么,因为你没有发布你的非工作代码,只是你的代码不是非常好,但工作的代码。我所看到的只是一个不是最好的方法的问题,无论语言如何。

我的建议是这样的:

  1. 如果出于某种原因您需要保留最初的 70 个 XML 问题,请通过调用 toString() 复制一份,然后再转换回 XML。这将破坏任何可能存在的对象依赖关系(尽管我不知道 AS2 XML 是否像真实对象一样)。
  2. 在每个循环中,删除您添加到新 XML 中的节点。这样,您就不必执行该内部循环来检查您是否已经使用过它(这确实是低效的)。
  3. 既然要删除它,为什么不把它移到新的 XML 中而不是创建一个新节点呢?这样你就不需要使用 Florian 建议的辅助变量而不是几个看起来像的表达式node.childNodes[1].childNodes[nextNode].nodeName;
  4. 在这一点上,您将只循环 20 次,或者您可以在循环时继续……没关系。任何一个都会导致 20 个循环和 20 个随机问题。
于 2012-06-23T03:12:45.940 回答