Skip to main content
Known Participant
June 26, 2012
Question

Parsing Soap Responses

  • June 26, 2012
  • 3 replies
  • 4248 views

Hello,

I am fairly new to CF and am trying to parse and then query a soap response from a third-party api. I have been able to get a response in xml format, but that is where I am stuck. Below the xml response I am getting an error that reads Element.LOGINRESPONSE.LOGINRESULT.XMLTEXT is undefined in LOGINXML.

I realize my code is a mess, but I am just trying out various things. Does anyone have any insight how to get at the Login Response variable in my soap response so that I can query it?

Thanks for any insight!!

<!--- WSDL --->

<cfset wsdl_url="http://somewebsite/sirewebsvc/sire.asmx?wsdl">

<cftry>

    <!--- Compose SOAP message to send to Web Service--->

    <cfsavecontent variable="soap"><?xml version="1.0" encoding="UTF-8" ?>

         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

             <soapenv:Body>

                 <Login xmlns="http://www.siretechnologies.com/">

      <LicenseKey>LicenseKey</LicenseKey>

      <Username>username</Username>

      <Password>password</Password>

      <LicenseType>2</LicenseType>

      <APIKey>APIKey</APIKey>

      <SiteKey></SiteKey>

      <CryptKey></CryptKey>

      <WebOnly>false</WebOnly>

    </Login>

              </soapenv:Body>

          </soapenv:Envelope>

    </cfsavecontent>

        <!--- Invoke web service to send message--->

        <cfhttp url="#wsdl_url#" method="post" >

            <cfhttpparam type="header" name="content-type" value="text/xml">

            <cfhttpparam type="header" name="SOAPAction" value="http://www.siretechnologies.com/Login">

            <cfhttpparam type="header" name="content-length" value="#len(soap)#">

            <cfhttpparam type="header" name="charset" value="utf-8">

            <cfhttpparam type="xml" name="message" value="#trim(soap)#">

        </cfhttp>

       

<p><cfoutput>#xmlFormat(cfhttp.fileContent)#</cfoutput> </p>

        <cfset MyXML = XmlParse(CFHTTP.FileContent)>

        XmlSearch(MyXML, "/LoginResponse/LoginResult/")

  <cfcatch type="any">

        <cfdump var="#cfcatch#">

    </cfcatch>

   

</cftry>

<cfsavecontent variable="XMLFile"><?xml version="1.0"?>

<LoginResponse>

    <LoginResult>

  ???How do I get this from above, or make it a variable???

    </LoginResult>

   

</LoginResponse>

</cfsavecontent>

<!--- Parse the XML --->

<cfset MyXMLDoc = xmlParse(XMLFile) />

<!--- Dump the XML --->

<h2>Dump</h2>

<cfdump var="#MyXMLDoc#">

<cfset MyNodes = xmlSearch(MyXMLDoc,'/LoginResponse/LoginResult')>

<cfoutput>

    <h2>Nodes</h2>

    <cfloop from="1" to="#arraylen(MyNodes)#" index="i">

        <!--- The array contents need to parsed so you can easily get at the child nodes children and attributes. --->

        <cfset LoginXML = xmlparse(MyNodes) />

        <b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.xmltext#<br>

       

    </cfloop>

</cfoutput>

--->

This topic has been closed for replies.

3 replies

BKBK
Community Expert
Community Expert
June 28, 2012

Two remarks from me:

1) This code, XmlSearch(MyXML, "/LoginResponse/LoginResult/"), simply hangs in the air. It is not a statement. Furthermore, the path "/LoginResponse/LoginResult/" suggests that the element LoginResponse is directly under the root. To be on the safe side I would use a double slash, so that any LoginResponse element anywhere will be match. You perhaps want to try something like

<cfset result = XmlSearch(MyXML, "//LoginResponse/LoginResult/")

2) In answer to the question,

<cfsavecontent variable="XMLFile"><?xml version="1.0"?>

<LoginResponse>

    <LoginResult>

  ???How do I get this from above, or make it a variable???

    </LoginResult>

</LoginResponse>

</cfsavecontent>

<cfsavecontent variable="XMLFile"><?xml version="1.0"?>

<cfloop array="#result#" index="idx">

<LoginResponse>

    <LoginResult><cfoutput>#idx.xmltext#</cfoutput></LoginResult>

</LoginResponse>

</cfloop>

</cfsavecontent>

<cfoutput>#xmlformat(XMLFile)#</cfoutput>

Known Participant
June 28, 2012

Thanks BKBK for the great advice. ☺

I am trying a bit of your code out and keep getting an error that says result is undefined. I am sure I am missing something really stupid, but how would I incorporate that into this process of viewing the xml output?

</cfsavecontent

12Robots
Participating Frequently
June 27, 2012

In my experience, this is one of the VERY few places in ColdFusion where you need to worry about Case Sensitivity.

The problem is here:

<b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.xmltext#<br>

This should be

<b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.XmlText#<br>

Jason


BKBK
Community Expert
Community Expert
June 28, 2012

12Robots wrote:

In my experience, this is one of the VERY few places in ColdFusion where you need to worry about Case Sensitivity.

The problem is here:

<b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.xmltext#<br>

This should be

<b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.XmlText#<br>


I think Coldfusion treats xmltext and XmlText the same, at least in this context.

12Robots
Participating Frequently
June 28, 2012

>> I think Coldfusion treats xmltext and XmlText the same, at least in this context.

In my experience, it does not. Did you try it?

Jason

Inspiring
June 27, 2012

You are on the right track from looking at your code.  You are doing a CFDUMP of the xml document, so what you need to do is to look at that output and see what is wrong with your structure reference.  Sometimes not all records in the xml doc have all of the same named nodes, so I find that in those cases you have to do a structKeyExists() before referencing a key.  The key to figuring this out will be the output from the CFDUMP.

You might want to add some error checking after the CFHTTP, to be sure that you get a 200 response back for status, and then before the xmlParse check to see if the document is actually an XML doc.  Sometimes you will get a response from a webservice that is an error message in HTML.  Other times you will get structured error information that is part of the XML response document.

I am not sure where you are going with the code that is in the CFSAVECONTENT tag - can you explain?

-reed

Known Participant
June 27, 2012

Thanks for the info Reed.

To be honest, I am not exactly sure if using cfsavecontent is correct. All I know is that I need to get a session key from this soap response and then use this to make other calls to the API in order to get documents. Would you use something different?