开发者

Howto get the deepest XML child matching certain attributes relative to the parrents in actionscript 3?

开发者 https://www.devze.com 2022-12-14 10:06 出处:网络
If I have the following XML in actionscript 3: <xml> <element1 x=\"10\" y=\"10\" width=\"200\" height=\"200\">

If I have the following XML in actionscript 3:

<xml>
   <element1 x="10" y="10" width="200" height="200">
       <child>text</child>
       <child x="0" y="0" width="100" height="100">
            content
       </child>
   </element1>
   <element2 x="10" y="10" width="200" height="200">
   </element2>
   <element3>
   </element3>
</xml>

This is just an example. Now, what I want to do is the following: get the deepest child element with x, y, width and height attributes which is within a certain location. So, if the given location is 50x100 then ((child.@x <= x) && (child.@x + child.@width >= x) && (child.@y <= y) && (child.@y + child.@height >= y)) must be valid

In this case it should return the second child element named child with attributes x=0 and y=0 - the code should also keep in mind that the childs of elements' positions are relative to the parents position. So, if the child's X is 0 and the parent's X is 100 then the absolute child position is 100.

I'm struggeling to get this right, could anyone help me out?

In the end, the method

getD开发者_如何学PythoneepestChildAtLoc(50, 100)

should in the above example code return

<child x="0" y="0" width="100" height="100">
            content
       </child>

I hope this makes sense. Thank in advance.

Edit:

Judging by the lack of replies this might not be making a lot of sense. In any way, this is what I came up with so far - though it returns "null" all the time so obviousely there is a flaw:

//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];
   trace(recProcessXML(pageCode, 0, x, y));
  }

  //recursively process childs to get the deepest child around the given position
  private static function recProcessXML(curElement:XML, depth:uint, targetX:uint, targetY:uint, totParentX:uint = 0, totParentY:uint = 0):XML
  {
   if (!curElement.children().length() > 0)
   { //this element has no further children
    return curElement;
   }
   else
   { //this element has further children
    var newChild:XML;
    var testChild:XML;
    for each (var child:XML in curElement.children())
    { //loop all children
     if (posInsideNode(child, totParentX, totParentY, targetX, targetY))
     { //if the child is still around the given position
      testChild = recProcessXML(child, depth + 1, targetX, targetY, child.@x + totParentX, child.@y + totParentY);
      if (testChild)
      { //if this child has further children
       newChild = testChild;
      }
     }
    }
    return newChild;
   }
   return null;
  }

  //returns whether the given position is inside the node
    private static function posInsideNode(child:XML, offsetX:uint, offsetY:uint, targetX:uint, targetY:uint):Boolean
    {
        trace("posInsideNode child: " + child.localName() + " -> " + child);
        //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;
    }

Notice also how the depth variable has not been used yet, while it obviousely should as the one with the highest depth should be returned. I'm not sure where to put this in though... any help?


After three days of overdosis coffee, headache and a ton of googling aswell as way too much trial-and-error I found the solution.

//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];
            trace(getDeepestElementAtPos(pageCode, 0, x, y)["xml"].toXMLString());
        }

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

精彩评论

暂无评论...
验证码 换一张
取 消