6 Replies Latest reply on Apr 4, 2007 6:50 PM by ntsiii

    Dynamic data display via XML querying

    C-Dubz
      Hey there. I'm new to Flex 2. Awesome product.

      I'd like to dynamically display the contents of an XML document. The document represents my music library (see snippet below). I'd like to load artists in one DataGrid and based on a selected artist, load the albums for that artist in a second DataGrid. Finally, when an album is selected, the album's songs are loaded in a third DataGrid.

      Based on the examples and documentation it sounds like I'll need to use ActionScript and event handlers. I also need to understand working with XML in Flex - specifically how to query XML. Lastly, the XML document is fairly large (~2MB), so I'll have some performance considerations.

      Any hints/docs/etc are greatly appreciated.

      -Chris


      The XML document looks like this:
      <MusicDatabase>
      <Artists>
      <Artist id="Artist_0">
      <Name>Led Zeppelin</Name>
      </Artist>
      ...
      </Artists>

      <Albums>
      <Album id="Album_0">
      <PerformingArtist id="0"/> <!-- this id maps to "Artist_0" -->
      <Name>Led Zeppelin</Name>
      </Album>
      ...
      </Albums>

      <Songs>
      <Song id="Song_1111">
      <Title>Good Times Bad Times</Title>
      <PerformingArtist id="Artist_0"/>
      <ContainedInAlbum id="Album_0"/>
      <SongLength ms="55217">3:55</SongLength>
      <Bitrate>128000</Bitrate>
      <Location>
      <Media id="Media_45" sn="-1059259224">MEDIA</Media>
      <Path>I:\music\Led Zeppelin\Led Zeppelin I\Good Times Bad Times.mp3</Path>
      </Location>
      </Song>
      ...
      </Songs>
      </MusicDatabase>
        • 1. Re: Dynamic data display via XML querying
          ntsiii Level 3
          First, 2mb will not be a performace problem to load. Use HTTPService for this.

          Sample code using HTTPService, e4x, handler function to populate a list item

          The DataGrid tag:
          <mx:DataGrid id="dg" dataProvider="{_xlcMyListData}" .../>
          <mx:DataGridColumn headerText="Id" dataField="@id" />
          <mx:DataGridColumn headerText="Name" dataField="Name" />

          The HTTPService tag:
          <mx:HTTPService id="service"
          resultFormat="e4x"
          url="library/musiclist.xml"
          result="onResult(event)" fault="..../>

          Script block declaration:
          import mx.rpc.Events.ResultEvent;
          [Bindable]private var _xlcMyListData:XMLListCollection;

          Result Handler function:
          private function onResult(oEvent:ResultEvent):void {
          var xmlResult:XML = XML(event.result); //converts result Object to XML. can also use "as" operator
          var xlMyListData:XMLList = xmlResult.Artists.Artist; //depends on xml format, is row data
          _xlcMyListData = new XMLListCollection(xlMyListData); //wrap the XMLList in a collection
          trace(_xlcMyListData.toXMLString()); //so you can see exactly how to specify dataField or build labelFunction
          }//onResult

          Post back if you get stuck.
          Tracy
          • 2. Re: Dynamic data display via XML querying
            ntsiii Level 3
            Note: while 2mb won't be slow to load, it might be slow to "render". just try it and see.

            Tracy
            • 3. Re: Dynamic data display via XML querying
              C-Dubz Level 1
              Hey Tracy. Thanks for the reply.

              I wish I got further than this, but I'm stuck on the following. My guess that this is a classpath issue, but I'm getting the same w/in my Eclipse Flex Development which I would assume has the classpath properly setup.

              E:/flex/projects/Lessons 143$ which mxmlc
              e:/software/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/bin/mxmlc.exe
              E:/flex/projects/Lessons 144$ mxmlc MusicLibrary.mxml
              Loading configuration file E:\software\Adobe\Flex Builder 2 Plug-in\Flex SDK 2\frameworks\flex-config.xml
              E:\flex\projects\Lessons\MusicLibrary.mxml(12): Error: Type was not found or was not a compile-time constant: ResultEvent.

              private function onResult(event:ResultEvent):void {

              Code is as follows:

              <mx:Script>
              <![CDATA[
              import mx.rpc.Events.ResultEvent;

              [Bindable]private var _xlcMyListData:XMLListCollection;

              private function onResult(event:ResultEvent):void {
              //converts result Object to XML. can also use "as" operator
              var xmlResult:XML = XML(event.result);
              //depends on xml format, is row data
              var xlMyListData:XMLList = xmlResult.Artists.Artist;
              //wrap the XMLList in a collection
              _xlcMyListData = new XMLListCollection(xlMyListData);
              //so you can see exactly how to specify dataField or build labelFunction
              trace(_xlcMyListData.toXMLString());
              }
              ]]>
              </mx:Script>

              Thanks!

              -Chris

              PS: I would be clearer if you these support forums at code formatting.
              • 4. Re: Dynamic data display via XML querying
                C-Dubz Level 1
                Got it. I need to import the following:

                import mx.rpc.events.ResultEvent; //using lowercase "events"
                import mx.collections.XMLListCollection;
                • 5. Re: Dynamic data display via XML querying
                  C-Dubz Level 1
                  Cool. Works.

                  Now I need to figure out how to load a second DataGrid with albums when a user selects an artist and similarly load a third DataGrid with songs when an album is selected.

                  I'll try using itemFocusIn and DataGridEvent to trigger the loading and XMLList to query for albums per artists and songs per albums.

                  Thanks.

                  -Chris
                  • 6. Re: Dynamic data display via XML querying
                    ntsiii Level 3
                    Enahnce the sample code like this. Crate a variable to hold the entire XML music library:
                    var _xmlMusicLibrary:XML

                    in the result handler, set that variable. inseatd of:
                    var xmlResult:XML = XML(event.result);
                    do
                    _xmlMusicLibrary:XML = XML(event.result);
                    Now you have the entire music library xml to use whenever you want.

                    Create a change event handler for the artist datagrid.
                    ...change="onChangeArtist(event)"

                    In that function search for the albums node using the value of the DataGrid selected item:
                    private function onChangeArtist(oEvent:Event):void
                    var xmlArtist:XML = XML(oEvent.target.selectedItem);
                    var sArtistId = xmArtist.@id;
                    var sPerformingArtistId:String = sArtistId.substring...you do this part
                    var xmlAlbums:XML = xmlMusicLibrary.albums.album.PerformingArtist.(@id==sPerformingArtistId);
                    AlbumDataGrid.dataProvider = xmlAlbums;

                    Tracy