Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

xmlSearch and xPath

Posted on 2011-09-09
7
Medium Priority
?
417 Views
Last Modified: 2012-05-12
Hi,

I have a variery of xml structures being returned from SOAP requests so am using xmlSearch() and xPath to extract structures of data however the attached structure is causing problems as I wish to retrieve all fields within the <result> part but am not sure how.

Any help much appreciated

cheers

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <v01:getUserDefaultPreferencesResponse xmlns:v01="http://webservice.api.xxx.com/v01/">
         <result xmlns:ns2="http://webservice.api.xxx.com/v01/" xmlns:ns3="http://schema.xxx.com/v01/">
            <ns3:DefaultAccountPreference defaultAccount="01023A6D084"/>
            <ns3:DefaultDateAndTimePreference TimeZone="GMT" DateFormat="MM/DD/YYYY" TimeFormat="12 hour" TTLFormat="Standard"/>
            <ns3:DefaultNumberOfrecordsPreference LargeTable="50" SmallTable="50"/>
            <ns3:DeleteConfirmPreference DeleteConfirmation="Confirm"/>
            <ns3:AutomaticPointerPreference ptrStatus="Disabled"/>
            <ns3:DefaultReportPreference ReportType="Overall Activity - Domains" GraphType="Bar"/>
         </result>
      </v01:getUserDefaultPreferencesResponse>
   </env:Body>
</env:Envelope>

Open in new window

0
Comment
Question by:Lmillard
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 52

Accepted Solution

by:
_agx_ earned 2000 total points
ID: 36511328
If you also want all of the attributes:

<!--- get "result" node --->
<cfset resultArray = xmlSearch(yourXMLString, "//result")>

<!--- create structure for storing results --->
<cfset data = structNew()>
<!--- assuming there's only 1 result node. --->
<cfloop array="#resultArray[1].XMLChildren#" index="node">
        <!--- extract all child fields and their attributes --->
      <cfset elemName = listLast(node.xmlName, ":")>
      <cfset data[elemName] = duplicate(node.xmlAttributes)>
</cfloop>

<!--- debugging display whatever values you want .... --->
<cfoutput>
#data.DefaultAccountPreference.defaultAccount#<br>
#data.DefaultDateAndTimePreference.DateFormat#<br>
#data.DefaultDateAndTimePreference.TimeFormat#<br>
... etc...
</cfoutput>

<!--- debugging, show full results --->
<cfdump var="#data#">
0
 
LVL 52

Expert Comment

by:_agx_
ID: 36511653
Add validation as needed.  If the fields/attributes can vary use structKeyExists() before accessing the structure elements.
0
 

Author Closing Comment

by:Lmillard
ID: 36511709
Awesome solution thanks! Works perfectly.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Lmillard
ID: 36516124
Hi agx, not sure if you will see this comment, if not I will repost on Monday but in the mean time.

I have a new twist on the xml structure where the depth is mroe than 1 level of results. now includes xmlChildren. is it possible to amend your example to handle the attached code?

Cheers
Leigh
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <v01:getResourceRecordsOfZoneResponse xmlns:v01="http://webservice.api.xxx.com/v01/">
         <ResourceRecordList xmlns:ns2="http://webservice.api.xxx.com/v01/" xmlns:ns3="http://schema.xxx.com/v01/">
            <ns3:ResourceRecord ZoneName="yyy.co.uk." Type="1" DName="www.yyy.co.uk." TTL="14400" Guid="04023A7008CE3817" ZoneId="03023A7008CE36C9" LName="www.yyy.co.uk." Created="2010-12-16T15:39:32.000Z" Modified="2010-12-16T15:39:32.000Z">
               <ns3:InfoValues Info1Value="82.153.226.171"/>
            </ns3:ResourceRecord>
            <ns3:ResourceRecord ZoneName="yyy.co.uk." Type="1" DName="mx.yyy.co.uk." TTL="14400" Guid="04023A7008CE3991" ZoneId="03023A7008CE36C9" LName="mx.yyy.co.uk." Created="2010-12-16T15:44:18.000Z" Modified="2010-12-16T15:44:18.000Z">
               <ns3:InfoValues Info1Value="82.153.226.171"/>
            </ns3:ResourceRecord>
         </ResourceRecordList>
      </v01:getResourceRecordsOfZoneResponse>
   </env:Body>
</env:Envelope>

Open in new window

0
 
LVL 52

Expert Comment

by:_agx_
ID: 36517806
There's actually another twist.  Since there's multiple "ResourceRecord" elements you can't use a structure. You'd need to use an array instead.

Keep in mind it only handles 2 levels. If you expect to go beyond that, you might be better off w/a recursive function.

<cfset resultArray = xmlSearch(xmlDoc, "//ResourceRecordList")>
<cfset results = []>
<cfloop array="#resultArray[1].XMLChildren#" index="node">
	  <cfset nodeData = duplicate(node.xmlAttributes)>
	  <cfloop array="#node.XMLChildren#" index="childNode">
          <cfset elemName = listLast(childNode.xmlName, ":")>
          <cfset nodeData[elemName] = duplicate(childNode.xmlAttributes)>
      </cfloop>
	  <cfset arrayAppend(results, nodeData)>
</cfloop>

<cfdump var="#results#">

Open in new window

0
 
LVL 52

Expert Comment

by:_agx_
ID: 36520380
>> Since there's multiple "ResourceRecord" elements you can't use a structure

Well .. you could. You just can't use the node name ie "ResourceRecord" as the structure key.  Structure key names must be unique. Otherwise, you'll overwrite the information and end up with only 1 ResourceRecord.
0
 

Author Comment

by:Lmillard
ID: 36528523
Hi,
Sorry for delay in response, I was away for a day or two.

This worked really well for me and returned everything perfectly. I am hoping that it only goes two levels deep but I keep getting surprises as I move through more SOAP requests on this project.

Thanks for your time on this, much appreciated. I think I will be doing some reading up on xml from here on.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

PROBLEM:  How to open a cfwindow or run a function on double click of a cfgrid row. One of my clients wanted to be able to double click on a row item to get more detailed information about a transaction and to be able to modify the line items i…
CFGRID Custom Functionality Series -  Part 1 Hi Guys, I was once asked how it is possible to to add a hyperlink in the cfgrid and open the window to show the data. Now this is quite simple, I have to use the EXT JS library for this and I achiev…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question