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 に答える