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.