5 Replies Latest reply on Jun 20, 2008 11:59 AM by ntsiii

    How can a DataGrid access nested XML data?

    berrisbob
      How can a DataGrid access nested data within XML? For instance, my XML looks like this:

      <mx:XMLList id="fakeList">
      <Product>
      <description>Prod Desc UP</description>
      <productIdentifier>
      <account>125103335555</account>
      <name>992</name>
      </productIdentifier>
      </Product>
      </mx:XMLList>

      I want to display the productIdentifier.name and description in my DataGrid. I can get the description to display, but not the name which is nested in the productIdentifier. Here is the DataGrid:

      <mx:DataGrid id="fakeGrid" width="100%" height="100%" rowCount="5" dataProvider="{fakeList}">
      <mx:columns>
      <mx:DataGridColumn dataField="?what_do_I_put_here?" headerText="Product" width="55"/>
      <mx:DataGridColumn dataField="description" headerText="Description" width="70"/>
      </mx:columns>
      </mx:DataGrid>

      I'm sure I could iterate over the XML data and build a new XMLList which grabbed the description value and nested name value and inserted them into a new XMLList at the same level. But I'm thinking there must be an easier way - like just putting the right thing in the dataField attribute in the DataGrid instead.

      Any help is greatly appreciated. Thanks.
        • 1. Re: How can a DataGrid access nested XML data?
          VarioPegged Level 2
          Use the labelFunction property of that column to display what you want.

          TS
          • 2. Re: How can a DataGrid access nested XML data?
            yupieyi Level 1
            I visit every single datagrid thread here as my application relies heavily on them.. good explanations with code is really appreciated.
            • 4. Re: How can a DataGrid access nested XML data?
              berrisbob Level 1
              Thanks VarioPegged - that does indeed solve the problem that I posted. I used a labelFunction - private function getName(item:Object, column:DataGridColumn): String - that returned item.child(4).child(1).toString(), and all was good. Unfortunately, what I posted was a bit simplified from the real situation, and I am not able to fully translate your solution into a solution for the actual situation.

              In the actual situation, the xml is not explicitly defined in the mxml, but rather is being returned from a web service call. If I specify the resultFormat of the web service operation as 'object', then my getName() method throws the following runtime error.

              TypeError: Error #1010: A term is undefined and has no properties.
              at mx.utils::ObjectProxy/ http://www.adobe.com/2006/actionscript/flash/proxy::callProperty()
              at PidList/getName()
              at mx.controls.dataGridClasses::DataGridColumn/itemToLabel()
              at mx.controls.dataGridClasses::DataGridBase/makeListData()
              at mx.controls::DataGrid/ http://www.adobe.com/2006/flex/mx/internal::setupRendererFromData()
              at mx.controls::DataGrid/commitProperties()
              at mx.core::UIComponent/validateProperties()
              at mx.managers::LayoutManager/validateProperties()
              at mx.managers::LayoutManager/doPhasedInstantiation()
              at Function/ http://adobe.com/AS3/2006/builtin::apply()
              at mx.core::UIComponent/callLaterDispatcher2()
              at mx.core::UIComponent/callLaterDispatcher()

              If I change the web service resultFormat to 'e4x', then I can get the DataGrid to display all the values in the xml, by using various versions of item.child()..., based on the value of the DataGridColumn parameter, but now no matter how many entities are returned from the web service, where each entity should represent one row in the DataGrid, only the first row of data shows up. The getName() method is always called exactly twice for each column in the grid, regardless of how many rows should be in the grid. And each time it is called, the item parameter contains the complete xml web service response, not just the part of it corresponding to the data for the current row in the DataGrid. I guess I could manually keep track of how many times getName() has been called, and based on the number of columns in the DataGrid convert that number into a row count so I could extract the correct row data from the item parameter. But I think I must be missing something and there is a simpler way.

              Again, any help is greatly appreciated.
              • 5. Re: How can a DataGrid access nested XML data?
                ntsiii Level 3
                Do not use resultFormat="object", itis the worst of both worlds.

                Sounds like you just have a problem witht the e4x expression you are using to reference the nodes you want to display.

                In your result handler, build your xml list expression step by step, tracing the content with toXMLString() to verify each step.

                It will be something like:
                var xmlResult:XML = XML(event.result);
                trace(xmlResult.toXMLString())
                var xlProducts:XMLList = xmlResult.Product;
                trace(xlProducts.length()); //should be the number of Product nodes.

                Note that "description" is a top level property so can be accessed directly using dataField="description".

                "name" will require a labelFunction because it is nested.

                do look at the example links I posted above.

                Tracy