0

我的情况是,我有一个 xml 文档,该文档将以下列方式更新:文档中围绕某个 x、y 位置的最深子项(取决于它的 x、y、宽度和高度属性)将获得一个新的子元素。如果存在多个具有相同深度的孩子,则更新底部的孩子。

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

//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(child.@x), totParentY + Number(child.@y));
                    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 ((child.@x.length() == 1) && (child.@y.length() == 1) && (child.@width.length() == 1) && (child.@height.length() == 1))
            {
                //if the new object is inside this child
                if ((Number(child.@x) + offsetX <= targetX) && (Number(child.@x) + offsetX + Number(child.@width) >= targetX) && (Number(child.@y) + offsetY <= targetY) && (Number(child.@y) + offsetY + Number(child.@height) >= 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 的直接子代而不是子代的子代(甚至更远)时才有效。

所以,问题是:我如何更新 pageCode 以包含更新后的 deepestElement 孩子,即使那个孩子是孩子的孩子等等?

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

4

2 回答 2

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);
        }
于 2009-12-23T21:47:16.367 回答
0

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

例如:

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

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

于 2009-12-23T15:30:00.760 回答