2009-12-23 31 views
0

我处于一种情况,我有一个xml文档,它将按照以下方式进行更新:文档中最深的子文件,它围绕某个x,y位置(取决于它的x,y,宽度和高度属性)将获得一个新的子元素。如果多个孩子以相同的深度存在,则会更新最下面的孩子。如何更新一个xml文档的孩子,无论它在actionscript 3中的“垂直索引”/深度?

我的第一步是要找到这个最深的孩子,这已经引起了问题,但我设法用下面的递归解决这个问题:

//returns the deepest element which surrounds the given position 
     private static function getDeepestElementAtPos(curElement:XML, depth:uint, targetX:uint, targetY:uint, totParentX:uint = 0, totParentY:uint = 0):Object 
     { 
      var deepestElement:Object = new Object(); 
      deepestElement["xml"] = curElement; 
      deepestElement["depth"] = depth; 

      var posDeeperChild:Object; 
      for each (var child:XML in curElement.children()) 
      { 
       if (posInsideNode(child, totParentX, totParentY, targetX, targetY)) 
       { 
        posDeeperChild = getDeepestElementAtPos(child, depth + 1, targetX, targetY, totParentX + Number([email protected]), totParentY + Number([email protected])); 
        if (posDeeperChild["depth"] > depth) deepestElement = posDeeperChild; 
       } 
      } 

      return deepestElement; 
     } 

     //returns whether the given position is inside the node 
     private static function posInsideNode(child:XML, offsetX:uint, offsetY:uint, targetX:uint, targetY:uint):Boolean 
     { 
      //if all required properties are given for an element with content 
      if (([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 1)) 
      { 
       //if the new object is inside this child 
       if ((Number([email protected]) + offsetX <= targetX) && (Number([email protected]) + offsetX + Number([email protected]) >= targetX) && (Number([email protected]) + offsetY <= targetY) && (Number([email protected]) + offsetY + Number([email protected]) >= targetY)) 
       { 
        return true; 
       } 
      } 
      return false; 
     } 

现在,下一步就是更新的完整代码如您在此处看到的:

//creates a new object at the given location, if existing elements are at the same location this will become a sub-element 
     public static function addNewObject(type:String, x:uint, y:uint):void 
     { 
      //get page code 
      var pageCode:XML = pageCodes[curPageId]; 

      //get deepest element at this position 
      var deepestElement:XML = getDeepestElementAtPos(pageCode, 0, x, y)["xml"]; 

      //define the new element 
      var newElement:XML = <newElement>tmp</newElement>; 

      //if it has to be added to the main tree 
      if (deepestElement == pageCode) 
      { 
       pageCode.appendChild(newElement); 
      } 
      else 
      { 
       //add the element to the child found earlier 
       deepestElement.appendChild(newElement); 

       //update the element in page code 
       // ! this is where I am stuck ! 
      } 
     } 

newElement仅用于实验目的。如果最深的孩子是主树,我确实设法更新了代码(所以没有匹配的孩子)。但是,如果有匹配的孩子或孩子内的孩子,我不知道如何更新最新的最深的孩子的主树。

下不起作用:

pageCode.insertChildAfter(deepestElement, newElement); 

因为,很显然,这仅deepestElement是pageCode的直接孩子,不是孩子的孩子的作品(甚至futher向下)。

因此,问题:如何更新pageCode以包含更新后的deepestElement子项,即使该子项是子项的子项等等?

在此先感谢,非常感谢所有帮助。

+0

道歉我是不可治愈的僧侣,但你要找的词是“深度”而不是“深度”。对不起,昨晚圣诞晚会稍微有些宿醉,似乎今天无法帮助自己。 – 2009-12-23 15:25:03

+0

我明白,帮助像我这样的外国人讲适当的英语。 :p – Tom 2009-12-23 17:57:58

回答

1

我想到返回的节点当然只是一个参考。这意味着如果我给它一个新的孩子,整个页面代码也会被更新。这工作:

//creates a new object at the given location, if existing elements are at the same location this will become a sub-element 
     public static function addNewObject(type:String, x:uint, y:uint):void 
     { 
      //get page code 
      var pageCode:XML = pageCodes[curPageId]; 

      //get deepest element at this position 
      var deepestElement:XML = getDeepestElementAtPos(pageCode, 0, x, y)["xml"]; 

      //define the new element 
      var newElement:XML = <newElement>tmp</newElement>; 

      //add the new element to the code 
      deepestElement.appendChild(newElement); 
     } 
0

您可能必须获取deepestElement的parentNode并在该节点上工作。首先删除旧版本的节点,然后插入更新的节点。另一种可能更有效的选择是只更新最深元素的属性和/或值,而不必替换它。

例如:

var parent:XMLNode = oldDeepestElement.parentNode; 
oldDeepestElement.removeNode(); 
parent.appendChild(newDeepestElement); 

我没有尝试过的代码,但这样的事情应该工作。无论如何,正如我所说的,如果可能的话,我会首先考虑更改节点的属性,而不是节点本身。

+0

我不明白为什么这会起作用。如果父节点有另一个父节点呢?它可能有100个父节点。 – Tom 2009-12-23 17:58:46

+0

详细说明,你只考虑1个父节点。尽管孩子的父母也有可能也有父母。 – Tom 2009-12-23 18:00:20

+0

也许我错误地解释了你的问题,我的意思是说,要在一个节点上工作,例如用其他东西代替它,你通常找到你想改变的节点的父节点并对其进行操作。无论您是递归地添加1个还是1000个父母都无关紧要,因为每个节点都有一个且只有中间父级。 – 2010-01-05 15:54:20

相关问题