3 Replies Latest reply on Feb 22, 2007 7:54 PM by jedale

    Getting Tree data with a twist

    jedale Level 1
      I just started playing around in flex and am excited about the possibilities. I read the previous question and answers on Getting Tree data by an HTTPService, but cannot get it to work with my xml data. I have an xml file which doesn't have the regular node tags for a tree's dataprovider. I was wondering if there was a way to get a tree to populate with data while using multiple tag names and descriptions encased within those tags. Here is an example of my xml data to show you what I mean:

      <?xml version="1.0" encoding="utf-8"?>

      <catalog>

      <product product="Nokia">
      <name>Nokia 6010</name>
      <description>Easy to use without sacrificing style, the Nokia 6010 phone offers functional voice communication supported by text messaging, multimedia messaging, mobile internet, games and more</description>
      <price>99.99</price>
      </product>

      <product product="Nokia">
      <name>Nokia 3100 Blue</name>
      <description>Light up the night with a glow-in-the-dark cover - when it's charged with light you can easily find your phone in the dark. When you get a call, the Nokia 3100 phone flashes in tune with your ringing tone. And when you snap on a Nokia Xpress-on™ gaming cover*, you'll get luminescent light effects in time to the gaming action.</description>
      <price>139</price>
      </product>
      </catalog>

      Using this data, I would expect to have one folder called "Nokia" which has two files called "Nokia 6010" and "Nokia 3100 Blue".

      So I have been searching the internet to see if I could get this xml format to work with a tree and this is the code I have so far:

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="horizontal"
      creationComplete="treeXML.send();">

      <mx:Script>
      <![CDATA[
      public function fixLabel(item:Object):String {
      var node:XML = XML(item);
      if( node.localName() == "product" )
      return unescape(node.@product);
      else if( node.localName() == "name" )
      return unescape(node.@name);
      else
      return '';
      }
      ]]>
      </mx:Script>

      <mx:HTTPService id="treeXML" url="data/catalog.xml" resultFormat="e4x"/>


      <mx:Panel width="30%" height="100%" layout="horizontal">
      <mx:Tree width="100%" showRoot="true" horizontalScrollPolicy="auto"
      height="100%" id="mytree" dataProvider="{treeXML.lastResult.node}"
      labelField="@name" labelFunction="fixLabel" />

      </mx:Panel>

      <mx:Panel width="70%" height="100%" id="panel1" layout="horizontal">
      </mx:Panel>

      </mx:Application>


      However, nothing is being populated in the tree. Can somebody please help me with this. I would think that this problem has been solved before but I don't know where to look.

      Thank you for your help.

        • 1. Re: Getting Tree data with a twist
          JabbyPandaUA Level 3
          You are doing everything right, although I do suspect that you are loading XML file into your app without web-server directly from your hard-drive.

          In this case, make sure, you had updated your Flex compiler settings like described here:
          http://polygeek.com/267_adobeflash_error-loading-xml-with-flex2

          And please install Flash Debug Player 9 - A VERY HUGE HELP FOR DEBUGGING your app inside browser.


          • 2. Re: Getting Tree data with a twist
            JabbyPandaUA Level 3
            Oopps, and another comment.

            Loading external data in Flash (Flex) is asynchronous process.
            You should read the data loaded from external source in event handler (Result) and assign it to the tree data Provider variable here

            See slightly modified code from your example below:

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="horizontal" creationComplete="onCreationComplete()">

            <mx:Script>
            <![CDATA[
            import mx.rpc.events.ResultEvent;
            import mx.collections.XMLListCollection;

            [Bindable]
            private var myXMLData : XMLListCollection;

            protected function onCreationComplete() : void {
            treeXML.send();

            }

            protected function onDataFetched(evt : ResultEvent) : void {
            var dataXML : XML = XML(evt.result);
            myXMLData = new XMLListCollection(new XMLList(dataXML.children()));
            }

            public function fixLabel(item:Object):String {

            var node:XML = XML(item);
            if( node.localName() == "product" )
            return unescape(node.@product);
            else if( node.localName() == "name" )
            return unescape(node.@name);
            else
            return '';
            }
            ]]>
            </mx:Script>

            <mx:HTTPService id="treeXML" url="data/catalog.xml" resultFormat="e4x" result="onDataFetched(event)"/>


            <mx:Panel width="30%" height="100%" layout="horizontal">
            <mx:Tree width="100%" showRoot="true" horizontalScrollPolicy="auto"
            height="100%" id="mytree" dataProvider="{myXMLData}"
            labelField="@name" labelFunction="fixLabel"/>

            </mx:Panel>

            <mx:Panel width="70%" height="100%" id="panel1" layout="horizontal">
            </mx:Panel>

            </mx:Application>
            • 3. Getting Tree data with a twist
              jedale Level 1
              Thanks for the reply. I definitely couldn't come up with that on my own at this stage of the game. I wonder if you could answer two more questions. How do I tell the node.@name to be a leaf instead of a folder? I changed a small piece in your code to handle the data inside the XML tags. Now I am getting two levels of folders with labels on them. Thats fine but how would I get rid of the the rest of the folders that I don't give a label?

              Say you have the following xml data:

              <?xml version="1.0" encoding="utf-8"?>

              <program name="someprogram">
              <system name="Mechanical 1">
              <docs name="other Systems">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              <docs name="Block Systems">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              <docs name="Block 2">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              <docs name="Suppressor">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              </system>
              <system name="Mechanical 2">
              <docs name="Pneumatics">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              <docs name="Block 1">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              <docs name="Block 2">
              <schematic name="Schematic" description="" url=""/>
              <guide name="Familiarization" url=""/>
              </docs>
              </system>
              <system name="Electrical"/>
              </program>

              How would I bind the selected item in the tree to some text boxes so that the relevant descriptions and url's would show up depending the selection? I know how to bind data when I don't use the "e4x" xml data format but I can't get around it by using a tree.

              I would love to hear any advice you could give me.
              Thanks again.