如何更新 xml 文档的子文档,无论其在 ActionScript 3 中的“垂直索引”/深度如何?

发布于 2024-08-15 19:02:07 字数 3933 浏览 2 评论 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 (([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 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 !
            }
        }

:只是暂时用于实验目的。如果最深的子树是主树(因此没有匹配的子树),我确实设法更新了代码。但是,当存在匹配的子级或子级中的子级时,我不知道如何使用更新的最深子级来更新主树。

以下内容不起作用:

pageCode.insertChildAfter(deepestElement, newElement);

因为显然,只有当 deepestElement 是 pageCode 的直接子元素而不是子元素的子元素(甚至更往下)时,这才有效。

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

提前致谢,非常感谢所有帮助。

I'm in a situation where I have a xml document which is going to be updated in the following way: The deepest child within the document which surrounds a certain x,y position (depending on it's x, y, width and height attributes) is going to get a new child element. If multiple childs exist with the same depth, the bottom one is updated.

My first step was to find this deepest child, this already caused problems, but I managed to solve this with the following recursion:

//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 (([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 1) && ([email protected]() == 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;
        }

Now, the next step is to update the complete code with the updated child, as you can see here:

//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 !
            }
        }

The newElement is just temporarily for experimental purposes. I did manage to update the code if the deepest child is the main tree (so there are no matching childs). However, when there are matching childs, or childs within childs, I have no idea how to update the main tree with the updated deepest child.

The following does not work:

pageCode.insertChildAfter(deepestElement, newElement);

Because, apparently, this only works if deepestElement is a direct child of the pageCode and not a child of a child (or even futher down).

So, the question: how do I update pageCode to contain the updated deepestElement child, even if that child is a child of a child and so on?

Thanks in advance, all help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奶茶白久 2024-08-22 19:02:07

我发现返回的节点当然实际上只是一个引用。这意味着如果我给它一个新的子元素,完整的页面代码也会更新。这有效:

//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);
        }

I figured out that the returned node is of course actually only a reference. Meaning that if I give it a new child, the complete page code will be updated too. This works:

//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);
        }
妖妓 2024-08-22 19:02:07

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

例如:

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

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

You probably have to get the parentNode of the deepestElement and work on that node. First removing the old version of the node and then inserting the updated one. Another choice which is probably more efficient is just update the attributes and/or the value of the deepestElement without having to replace it.

for example:

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

I haven't tried the code but something like this should work. In any case, as I said I would first consider changing the attributes of the node and not the node itself if this is possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文