Search code examples
xmlcoldfusionxml-parsingcoldfusion-9

Parsing Complexed XML file using Coldfusion


I am parsing an XML file with vehicle data and specifications. I am having problems looping over certain nodes to get multiple values. Here is some code I have working.

<cffile action="READ" file="c:\websites\db-utils\sample.xml" variable="xmlData">

<cfscript> 
    myxmldoc = XmlParse(xmlData); 
    modelNumber = XmlSearch(myxmldoc, "//basic_data/model_number"); 
    modelNumber = modelNumber[1].XmlText;

    enginename = XmlSearch(myxmldoc, "//engines/engine"); 
    enginename = enginename[1].XmlAttributes.name;

    camtype = XmlSearch(myxmldoc, "//engines/engine/cam_type"); 
    camtype = camtype[1].XmlText;

    transmissionname = XmlSearch(myxmldoc, "//transmissions/transmission"); 
    transmissionname = transmissionname[1].XmlAttributes.name;
</cfscript>
<cfoutput>
    Model Number: #modelNumber# <br />
    Engine: #enginename#<br>
    Cam: #camtype#<br>
    Trans: #transmissionname#<br>
</cfoutput>

The XML I am have problem with is when I get deeper and need to loop over nodes. Her is a snippet of the XML.

<decoded_data>
    <decoder_messages></decoder_messages>
        <query_responses>
            <query_response identifier="1" transaction_id="CC969FDA9C2B546EEC0A8036F19C7A8543A7148E">
                <query_error></query_error>
                    <us_market_data>
                        <us_styles count="1">
                            <style name="XLE 4dr Sedan" vehicle_id="400892838" complete="Y" market="US Light-Duty" fleet="N">
                                <basic_data></basic_data>
                                <pricing></pricing>
                                <engines></engines>
                                <transmissions></transmissions>
                                <specifications>
                                    <category name="Drive Type"><specification name="Drive Type">FWD</specification></category>
                                    <category name="Fuel Tanks"><specification name="Fuel Tank 1 Capacity (Gallons)">17</specification></category>
                                    <category name="Interior Dimensions">
                                        <specification name="Cargo Volume">15.4</specification>
                                        <specification name="Passenger Volume">102.7</specification>
                                    </category>
                                    <category name="Measurements of Size and Shape">
                                        <specification name="Front Track Width">62.4</specification>
                                        <specification name="Ground Clearance">6.1</specification>
                                        <specification name="Height">57.9</specification>
                                        <specification name="Length">190.9</specification>
                                        <specification name="Rear Track Width">62</specification>
                                        <specification name="Wheelbase">109.3</specification>
                                        <specification name="Width">71.7</specification>
                                    </category>

This is where is am having difficulty finding how to loop over the specifications and the categories within them. Also getting both the 'name' and the actual 'specification'. I am kinda going the right direction with this code:

<cfset specNodes = xmlSearch(myxmldoc,'//specifications/category')>
<cfoutput>
<cfloop from="1" to="#arraylen(specNodes)#" index="i">
   <cfset specXML = xmlparse(specNodes[i])>
    #specXML#<br>   
</cfloop>
</cfoutput>

But I am not quite there... any help would be appreciated.


Solution

  • You could do that as follows:

    <cfloop from="1" to="#arraylen(specNodes)#" index="i">
    
        <h3>#specNodes[i].XmlAttributes.name#</h3>  
    
        <cfset specChildren = specNodes[i].specification />
    
        <cfloop from="1" to="#arraylen(specChildren)#" index="j">
    
            <br/>#specChildren[j].XmlAttributes.name# = #specChildren[j].XmlText#
    
        </cfloop>   
    
    </cfloop>
    

    Which gives you:

    **Drive Type**
    
    Drive Type = FWD
    
    **Fuel Tanks**
    
    Fuel Tank 1 Capacity (Gallons) = 17
    
    **Interior Dimensions**
    
    Cargo Volume = 15.4
    Passenger Volume = 102.7
    
    **Measurements of Size and Shape**
    
    Front Track Width = 62.4
    Ground Clearance = 6.1
    Height = 57.9
    Length = 190.9
    Rear Track Width = 62
    Wheelbase = 109.3
    Width = 71.7