Archive for June, 2008

02
Jun

YUI DataSource parseXMLData improved

While working with the YUIDataSource“, I wanted to feed web service generated XML to the user interface which would then populate a YUI “DataTable”.  The default “parseXMLData” function that comes with YUI seems rather limited.  It will handle fetching a “resultNode” and any child nodes which have text data and also attributes of the “resultNode”.  So XML like this works OK.

<artist-list count="1" offset="0">
     <artist id="6fe07aa5-fec0-4eca-a456-f29bff451b04" type="Group" ext:score="100">
         <name>Weezer</name>
         <sort-name>Weezer</sort-name>
     </artist>
</artist-list>

Using the default “parseXMLData”, I could retrieve any of the attributes or child node text of the <artist> node.  But what about XML like this?

<artist-list count="1" offset="0">
     <artist id="6fe07aa5-fec0-4eca-a456-f29bff451b04" type="Group" ext:score="100">
          <name>Weezer</name>
          <sort-name>Weezer</sort-name>
          <life-span begin="1992-02-14"/>
     </artist>
</artist-list>

In this example, the “begin” attribute is not accessible to me.  But I have a patch that makes it work.  I thought the introduction of XPath would be the correct way to express what value to access in the XML.  Granted the patch is very limited and does not implement all possible XPath possibilities but it’s a start.

        myDataSource.responseSchema = {
                  resultNode: 'artist',
                  field:  ["sort-name",
                            "type",
                            {xpath:"life-span/@begin", key:"begin"},
                            {xpath:"life-span/@end", key:"end"},
                            {key:"ext:score", parser:YAHOO.util.DataSource.parseNumber},
                             "id"]};

Another issue I have with “parseXMLData” is when the “resultNode” and the “field” are the same.

<artist id="070d193a-845c-479f-980e-bef15710653e" type="Person">
   <name>Prince</name>
   <sort-name>Prince</sort-name>
   <life-span begin="1958-06-07"/>
   <alias-list>
       <alias>The Artist Formerly Known as Prince</alias>
       <alias>Symbol</alias>
       <alias>Formerly Prince</alias>
       <alias>T.A.F.K.A.P.</alias>
     </alias-list>
</artist>
myDataSource.responseSchema = {  resultNode: 'alias', field: ['alias'] };

A simple patch to “parseXMLData” handles this scenario by checking if the “resultNode” is equal to the current field, then return the “nodeValue”.

Download patch here