Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Flex Tree from Complex XML

Posted on 2009-05-13
6
Medium Priority
?
4,488 Views
Last Modified: 2012-05-06
Hi Genius'

I have been struggling with this for about a week now so it is time to ask for some help.
I have a well formed XML file that I receive from a server (please see original.xml) and I would like to represent it as a tree that the user can click on a leaf and be able to edit the elements associated with that item in fields to the right of the tree (either a dataGrid or a series of textInput fields.)

My problem is how to get it into a tree and tightly bound to the XML.

All of the examples that I have found mysteriously change from xml with elements in it into XML with only attributes (something like tree_1.xml). This is not useful as the actual data I am using has many elements attached to each leaf and sometimes multiple attributes.

My gut feeling (with very little experience in these matters) is to reformat the original.xml into a tree structure (like tree_2.xml), bind it to an XMLListCollection and create a tree by using a labelFunction.

I have two problems with this approach:

    1. XMLListCollection does not seem to like the tree structure XML
    2. If I write a labelFunction like:

private function getTreeLabel(item:Object):String
            {
                var node:XML = XML(item);
                if( node.localName() == "Desc" )
                    return node;
               else
                   return null;
            }

I can do this by using the HTTPService as the dataProvider I get the branches and leaves I want but I also get a blank tree item for each of the nulls

I hope I have described the problem clearly as it is now very late here.
Going around in circles and very tired, so any help would be much appreciated.

Best Regards,






original.xml
 
<treeID>103</treeID>
<treeType>Oak</treeType>
<branches>
    <branch>
        <id label="branch ID" dbid="0">290</id>
        <branchCode label="branch Code" dbid="1">A</branchCode>
        <branchTitle label="Title" dbid="2">Small Branch</branchTitle>
    </branch>
    <branch>
        <id label="branch ID" dbid="0">391</id>
        <branchCode label="branch Code" dbid="1">B</branchCode>
        <branchTitle label="Title" dbid="2">Big Branch</branchTitle>
    </branch>
</branches>
 
<leaves>
    <leaf>
        <id label="leaf ID" dbid="0">48</id>
        <leafCode label="leaf Code" dbid="1">xBBLeaf1</leafCode>
        <leafDesc label="leaf Description" dbid="3">Big Branch Leaf One</leafDesc>
        <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
        <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
        <leafSize label="Leaf Size" dbid="10">123</leafSize>
    </leaf>
    <leaf>
        <id label="leaf ID" dbid="0">138</id>
        <leafCode label="leaf Code" dbid="1">yBBLeaf2</leafCode>
        <leafDesc label="leaf Description" dbid="3">Big Branch Leaf Two</leafDesc>
        <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
        <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
        <leafSize label="Leaf Size" dbid="10">124</leafSize>
    </leaf>
    <leaf>
        <id label="leaf ID" dbid="0">49</id>
        <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
        <leafDesc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
        <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
        <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
        <leafSize label="Leaf Size" dbid="10">125</leafSize>
    </leaf>
    <leaf>
        <id label="leaf ID" dbid="0">44</id>
        <leafCode label="leaf Code" dbid="1">SBLeaf1</leafCode>
        <leafDesc label="leaf Description" dbid="3">Small Branch Leaf One</leafDesc>
        <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
        <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
        <leafSize label="Leaf Size" dbid="10">126</leafSize>
    </leaf>
    <leaf>
        <id label="leaf ID" dbid="0">42</id>
        <leafCode label="leaf Code" dbid="1">SBLeaf2</leafCode>
        <leafDesc label="leaf Description" dbid="3">Small Branch Leaf Two</leafDesc>
        <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
        <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
        <leafSize label="Leaf Size" dbid="10">127</leafSize>
    </leaf>
</leaves>
 
=================================================================
 
tree_1.xml
 
<tree>
<branches>
    <branch id="290" branchCode="A" label="Small Branch" />
        <leaves>
            <branch id="44" leafCode="xSBLeaf1" label="Small Branch Leaf One" />
            <branch id="42" leafCode="xSBLeaf1" label="Small Branch Leaf Two" />
            <branch id="49" leafCode="Uni" label="The Multi Leaf" />
        </leaves>
    </branch>
    <branch id="391" branchCode="B" label="Big Branch" />
        <leaves>
            <branch id="48" leafCode="xBBLeaf1" label="Big Branch Leaf One" />
            <branch id="138" leafCode="xBBLeaf1" label="Big Branch Leaf Two" />
            <branch id="49" leafCode="Uni" label="The Multi Leaf" />
        </leaves>
    </branch>
</branches>
</tree>
 
====================================================================
 
 
<tree>
<branches>
    <branch id label="branch ID" dbid="0">290</id>
        <branchCode label="branch Code" dbid="1">A</branchCode>
        <Desc label="Title" dbid="2">Small Branch</branchTitle>
        <leaves>
            <leaf>
                <id label="leaf ID" dbid="0">49</id>
                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
                <Desc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">125</leafSize>
            </leaf>
            <leaf>
                <id label="leaf ID" dbid="0">44</id>
                <leafCode label="leaf Code" dbid="1">SBLeaf1</leafCode>
                <Desc label="leaf Description" dbid="3">Small Branch Leaf One</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">126</leafSize>
            </leaf>
            <leaf>
                <id label="leaf ID" dbid="0">42</id>
                <leafCode label="leaf Code" dbid="1">SBLeaf2</leafCode>
                <Desc label="leaf Description" dbid="3">Small Branch Leaf Two</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">127</leafSize>
            </leaf>
        </leaves>
    </branch>
    <branch>
        <id label="branch ID" dbid="0">391</id>
        <branchCode label="branch Code" dbid="1">B</branchCode>
        <Desc label="Title" dbid="2">Big Branch</branchTitle>
        <leaves>
            <leaf>
                <id label="leaf ID" dbid="0">48</id>
                <leafCode label="leaf Code" dbid="1">xBBLeaf1</leafCode>
                <Desc label="leaf Description" dbid="3">Big Branch Leaf One</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">123</leafSize>
            </leaf>
            <leaf>
                <id label="leaf ID" dbid="0">138</id>
                <leafCode label="leaf Code" dbid="1">yBBLeaf2</leafCode>
                <Desc label="leaf Description" dbid="3">Big Branch Leaf Two</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">124</leafSize>
            </leaf>
            <leaf>
                <id label="leaf ID" dbid="0">49</id>
                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
                <Desc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
                <leafSize label="Leaf Size" dbid="10">125</leafSize>
            </leaf>
        </leaves>        
    </branch>
</branches>
</tree>

Open in new window

0
Comment
Question by:enjay99
  • 3
  • 3
6 Comments
 
LVL 10

Expert Comment

by:mplord
ID: 24374086
You are right, the tree XML you provide to the Tree control will need to be formatted in a way that the Tree control will accept. So you'll have to transform the XML you get from the HTTPService request before you can use it exactly as you need in the tree, then once edited transform it back to the format you require before sending it back for update etc.

Your tree_2.xml had to be modified slightly as your tags were not matching correctly (probably your tiredness right ;) - the following example should help you see how to show the complete (bound) tree including element values.

Remember though that elements are still children of the enclosing tags, so will always appear as child nodes in the tree. If for example you want to show the id element value as the label for the id node, you'll have to reformat your XML to provide the id value as an attribute of the id node then update the getTreeLabel function to build the label string.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();">
 
	<mx:Script>
		<![CDATA[
			[Bindable] private var model:XML = 
				<tree>
					<branches>
					    <branch>
					    	<id label="branch ID" dbid="0">290</id>
					        <branchCode label="branch Code" dbid="1">A</branchCode>
					        <branchTitle label="Title" dbid="2">Small Branch</branchTitle>
					        <leaves>
					            <leaf>
					                <id label="leaf ID" dbid="0">49</id>
					                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
					                <leafDesc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">125</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">44</id>
					                <leafCode label="leaf Code" dbid="1">SBLeaf1</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Small Branch Leaf One</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">126</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">42</id>
					                <leafCode label="leaf Code" dbid="1">SBLeaf2</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Small Branch Leaf Two</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">127</leafSize>
					            </leaf>
					        </leaves>
					    </branch>
					    <branch>
					        <id label="branch ID" dbid="0">391</id>
					        <branchCode label="branch Code" dbid="1">B</branchCode>
					        <branchTitle label="Title" dbid="2">Big Branch</branchTitle>
					        <leaves>
					            <leaf>
					                <id label="leaf ID" dbid="0">48</id>
					                <leafCode label="leaf Code" dbid="1">xBBLeaf1</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Big Branch Leaf One</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">123</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">138</id>
					                <leafCode label="leaf Code" dbid="1">yBBLeaf2</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Big Branch Leaf Two</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">124</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">49</id>
					                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
					                <leafDesc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">125</leafSize>
					            </leaf>
					        </leaves>        
					    </branch>
					</branches>
				</tree>
				
				private function init():void
				{
					tree.dataProvider = model;
				}	
				
				private function getTreeLabel(item:Object):String
				{
					var node:XML = XML(item);
					if( node.localName() == null )
						return node.toString();
					else
					{
						switch (node.localName())
						{
							//eg
							case "leafDesc":
								return "leafDesc: " + node.@label;
								break;
						}						
					}
					// default
					return node.localName();
				}
		]]>
	</mx:Script>
 
	<mx:Tree id="tree" horizontalCenter="0" verticalCenter="7" width="472" height="380" labelFunction="getTreeLabel"></mx:Tree>
	
</mx:Application>

Open in new window

0
 

Author Comment

by:enjay99
ID: 24382573
Dear mplord,

Thank you for your excellent response, what a great service.

As you mentioned though all the elements are still children of the enclosing tags, so will always appear as child nodes in the tree.

I was hoping to use the getTreeLabel function to only list the Title of the branch or leaf, but bind to the rest of the data elements of the leaf for editing in another part of the screen.

Perhaps that is asking a bit too much of the flex tree and will have to create a tree of only the Titles and somehow "point" to the data for editing.
0
 
LVL 10

Accepted Solution

by:
mplord earned 2000 total points
ID: 24383827
You can use a custom data descriptor for the tree to help with this.

I've created a new class CustomDescriptor which overrides DefaultDataDescriptor, and is provided to the tree as it's dataDescriptor.

You'll have to add an event to detect when you've selected a node in the tree, and bind your editing fields to the node depending on it's type etc.

Hope this helps.

###### MAIN APPLICATION
 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();" xmlns:my="*">
 
	<mx:Script>
		<![CDATA[
			[Bindable] private var model:XML = 
				<tree>
					<branches>
					    <branch>
					    	<id label="branch ID" dbid="0">290</id>
					        <branchCode label="branch Code" dbid="1">A</branchCode>
					        <branchTitle label="Title" dbid="2">Small Branch</branchTitle>
					        <leaves>
					            <leaf>
					                <id label="leaf ID" dbid="0">49</id>
					                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
					                <leafDesc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">125</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">44</id>
					                <leafCode label="leaf Code" dbid="1">SBLeaf1</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Small Branch Leaf One</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">126</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">42</id>
					                <leafCode label="leaf Code" dbid="1">SBLeaf2</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Small Branch Leaf Two</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">A</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">127</leafSize>
					            </leaf>
					        </leaves>
					    </branch>
					    <branch>
					        <id label="branch ID" dbid="0">391</id>
					        <branchCode label="branch Code" dbid="1">B</branchCode>
					        <branchTitle label="Title" dbid="2">Big Branch</branchTitle>
					        <leaves>
					            <leaf>
					                <id label="leaf ID" dbid="0">48</id>
					                <leafCode label="leaf Code" dbid="1">xBBLeaf1</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Big Branch Leaf One</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">123</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">138</id>
					                <leafCode label="leaf Code" dbid="1">yBBLeaf2</leafCode>
					                <leafDesc label="leaf Description" dbid="3">Big Branch Leaf Two</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">B</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">124</leafSize>
					            </leaf>
					            <leaf>
					                <id label="leaf ID" dbid="0">49</id>
					                <leafCode label="leaf Code" dbid="1">Unileaf</leafCode>
					                <leafDesc label="leaf Description" dbid="3">The Multi Leaf</leafDesc>
					                <onbranchs label="Appear on branchs" dbid="5">AB</onbranchs>
					                <leafDate label="Leaf Date" dbid="7">12-04-09</leafDate>
					                <leafSize label="Leaf Size" dbid="10">125</leafSize>
					            </leaf>
					        </leaves>        
					    </branch>
					</branches>
				</tree>
				
				private function init():void
				{
					tree.dataProvider = model;
				}	
				
				private function getTreeLabel(item:Object):String
				{
					var node:XML = XML(item);
					if( node.localName() == null )
						return node.toString();
					else
					{
						switch (node.localName())
						{
							//eg
							case "leaf":
								return "leaf: " + node.leafDesc.children()[0].toString();
								break;
							case "branch":
								return "branch: " + node.branchTitle.children()[0].toString();
								break;
						}						
					}
					// default
					return node.localName();
				}
		]]>
	</mx:Script>
 
	<mx:Tree dataDescriptor="{new CustomDescriptor()}" id="tree" horizontalCenter="0" verticalCenter="7" width="472" height="380" labelFunction="getTreeLabel"></mx:Tree>
	
</mx:Application>
 
 
###### CustomDescriptor.as
 
package
{
	import mx.collections.ICollectionView;
	import mx.collections.XMLListCollection;
	import mx.controls.treeClasses.DefaultDataDescriptor;
	
	public class CustomDescriptor extends DefaultDataDescriptor
	{
		public function CustomDescriptor()
		{
		}
 
		override public function hasChildren(node:Object, model:Object = null):Boolean
		{
			if (node is XML)
			{
				var xmlnode:XML = node as XML;
				switch (xmlnode.localName())
				{
					case "leaf":
						return false;
					case "branch":
						return ((xmlnode.leaves as XMLList).length() > 0);
				}
			}
			return super.hasChildren(node, model);
		}
 
		override public function isBranch(node:Object, model:Object = null):Boolean
		{
			if (node is XML)
			{
				var xmlnode:XML = node as XML;
				if (xmlnode.localName() == "leaf") return false;
			}
			return super.hasChildren(node, model);
		}
 
		override public function getChildren(node:Object, model:Object = null):ICollectionView
		{
			if (node is XML)
			{
				var xmlnode:XML = node as XML;
				switch (xmlnode.localName())
				{
					case "branch":
						return new XMLListCollection(xmlnode.leaves.leaf as XMLList);
				}
			}
			return super.getChildren(node, model);
		}
 
	}
}

Open in new window

0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 

Author Comment

by:enjay99
ID: 24392597
Fantastic !!!

Thank you mplord.
0
 

Author Comment

by:enjay99
ID: 24392617
Sorry mplord,

Could you please ping one more note, so that I can award points.
I said thank you in a comment without realizing how things work.
0
 
LVL 10

Expert Comment

by:mplord
ID: 24393668
Hi - no problem :)
0

Featured Post

Get Certified for a Job in Cybersecurity

Want an exciting career in an emerging field? Earn your MS in Cybersecurity and get certified in ethical hacking or computer forensic investigation. WGU’s MSCSIA degree program was designed to meet the most recent U.S. Department of Homeland Security (DHS) and NSA guidelines.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
Your business may be under attack from a silent enemy that is hard to detect. It works stealthily in the shadows to access and exploit your critical business information, sensitive confidential data and intellectual property, for commercial gain. T…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question