Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Flex Tree from Complex XML

Posted on 2009-05-13
6
4,477 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 500 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
Easy, flexible multimedia distribution & control

Coming soon!  Ideal for large-scale A/V applications, ATEN's VM3200 Modular Matrix Switch is an all-in-one solution that simplifies video wall integration. Easily customize display layouts to see what you want, how you want it in 4k.

 

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

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

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

Suggested Solutions

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…
Some of the SEO trends we might expect in 2017.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

791 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