Solved

using coldfusion to access xml namespaced elements

Posted on 2011-09-14
10
427 Views
Last Modified: 2012-05-12
Hi,

Is it possible to return a structure of all data returned in any namespaced element /node. Please see attached code.

I am new to xml so please forgive my mixup in terminology

Regards
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
Comment
Question by:Lmillard
  • 4
  • 3
  • 3
10 Comments
 
LVL 11

Expert Comment

by:Brijesh Chauhan
ID: 36535313
Just use xmlParse

<cfsavecontent variable="returnedVar">
<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>
</cfsavecontent>



<cfdump var="#xmlParse(returnedVar)#">

Open in new window

0
 

Author Comment

by:Lmillard
ID: 36535451
Sorry, I wasn't very clear, I just want to grab anything within a particular namespace, in this case ns3 (is that even a namespace??)
0
 
LVL 11

Accepted Solution

by:
Brijesh Chauhan earned 250 total points
ID: 36535941
You can use XML search to find the element, I am for some reason not able to find ns3: record if I try to search, probably the XPATH expression needs to be corrected.

You can also loop to get the element values that you are looking for...

<cfset arrayResult = xmlSearch(returnedVar,'/env:Envelope/env:Body/*') />

<cfloop from="1" to="#arraylen(arrayResult[1].XmlChildren[1].XmlChildren)#" index="i">
	<cfset ns3_ResourceRecord = arrayResult[1].XmlChildren[1].XmlChildren[i].XmlAttributes />
    <cfdump var="#ns3_ResourceRecord#">
</cfloop>

Open in new window

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 11

Expert Comment

by:Brijesh Chauhan
ID: 36535943
<cfset arrayResult = xmlSearch(returnedVar,'/env:Envelope/env:Body/*') />

<cfloop from="1" to="#arraylen(arrayResult[1].XmlChildren[1].XmlChildren)#" index="i">
	<cfset ns3_ResourceRecord = arrayResult[1].XmlChildren[1].XmlChildren[i].XmlAttributes />
    <cfdump var="#ns3_ResourceRecord#">
</cfloop>

Open in new window

0
 

Author Comment

by:Lmillard
ID: 36536303
This does bring back the resourceRecord elements but not the infoValues. Pretty sure the code could be amended to do this but I need to search on namespace (ns3) as there is a variation of layouts coming back to me
0
 
LVL 52

Expert Comment

by:_agx_
ID: 36536542
<cfset result = xmlSearch(xmlDoc, "//*[namespace-uri()='http://schema.xxx.com/v01/']")>
0
 

Author Comment

by:Lmillard
ID: 36537961
I have added the code above but am still getting some odd results, the arrayLen is 4 now
<cfset xmlDoc = '<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>'>

<!--- switch between arrayResult retrieval methods --->
<cfset arrayResult = xmlSearch(xmlDoc,'/env:Envelope/env:Body/*') />
<cfset arrayResult = xmlSearch(xmlDoc, "//*[namespace-uri()='http://schema.xxx.com/v01/']")>

<cfloop from="1" to="#arraylen(arrayResult[1].XmlChildren[1].XmlChildren)#" index="i">
	<cfset ns3_ResourceRecord = arrayResult[1].XmlChildren[1].XmlChildren[i].XmlAttributes />
    <cfdump var="#ns3_ResourceRecord#">
</cfloop>


<cfdump var="#arrayResult#">

Open in new window

0
 
LVL 52

Assisted Solution

by:_agx_
_agx_ earned 250 total points
ID: 36538102
>> [namespace-uri()='http://schema.xxx.com/v01/']"

That will extract all elements with the "ns3" prefix - including the child InfoValues  elements.  If you only want to retrieve the parent element  ie "ResourceRecord", add a filter on local-name:

<cfset arrayResult = xmlSearch(xmlDoc, "//*[local-name() = 'ResourceRecord' and namespace-uri()='http://schema.xxx.com/v01/']")>

Open in new window


Then you can extract the attributes just like you were doing before:

<cfset results = []>
<cfloop array="#nodeArray#" 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: 36538155
Oops.. It would be nice if the array name matched too ;-)

<cfset nodeArray = xmlSearch(xmlDoc, "//*[local-name() = 'ResourceRecord' and namespace-uri()='http://schema.xxx.com/v01/']")>
....
<cfloop array="#nodeArray#" index="node">
...
0
 

Author Closing Comment

by:Lmillard
ID: 36538215
Thank you very much to both of you, an elegant solution which works over the scenarios I have come across to date. much appreciated.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
Recently while working on a project I got a very annoying cfdocument has no body error message. I had never seen this error before. So I checked the code. The code was pretty simple; it was Just showing me the cfdocumnt tag and inside that tag a …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

810 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