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[i]) />
<b>SessionKey:</b> #LoginXML.LoginResponse.LoginResult.xmltext#<br>
</cfloop>
</cfoutput>
--->
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
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
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>
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.
Thanks for the response. I think it does matter, because I have made everything XmlText and the code seems to be working better. Also, when I do a cfdump of my xml, the structure uses XmlText, not xmltext. I have not solved all of my problems yet, but your response is very helpful.
I will post my solution when/if I get one. ☺
Yea, I should ahve remembered to mention that. Incorrect case is the single biggest problem I've had when dealing with the XML docs coming back from webservices. Not just the XmlText vs XMLText (which is from the CF Server side) but even more so from web services that are inconsistent in their use of case for the XML elements. Whatever you see in the CFDUMP is what you need to use.
-reed
I think I figured it out. Thanks to all who helped!! If anyone is interested, this is how I retrieved the session key from my Soap response.
<!--- WSDL --->
<cfset wsdl_url="http://SOMEURL/sire.asmx?wsdl">
<!--- 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>LicKey</LicenseKey>
<Username>user</Username>
<Password>pass</Password>
<LicenseType>2</LicenseType>
<APIKey>API</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)>
<cfdump var="#MyXml#">
<cfset responseNodes = xmlSearch(MyXml,"//*[ local-name() = 'LoginResponse' ]")>
<cfdump var="#responseNodes#">
<cfoutput>
<cfloop from="1" to="#arraylen(responseNodes)#" index="i">
<cfset TheXML = xmlparse(responseNodes[i])>
<cfset SesKey = "#TheXML.LoginResponse.LoginResult.XmlText#">
<b>SessionKey:</b> #TheXML.LoginResponse.LoginResult.XmlText#<br>
<b>Session Key:#SesKey#
</cfloop>
</cfoutput>
12Robots wrote:
>> I think Coldfusion treats xmltext and XmlText the same, at least in this context.
In my experience, it does not. Did you try it?
I have just tried the following example, using xmltext. There were no problems. Then again, I am on Coldfusion 10. Coldfusion versions might perhaps be behaving differently on this issue.
<!--- Setup some XML to work with --->
<cfxml variable="XMLFile"><root>
<header style="st1">
<user>1</user>
</header>
<book>
<isbn>0321330110</isbn>
<title>Macromedia ColdFusion MX 7 Certified Developer Study Guide</title>
<author>Ben Forta</author>
</book>
<header style="st2">
<user>2</user>
</header>
<book>
<isbn>0596004206</isbn>
<title>Learning XML, Second Edition</title>
<author>Erik Ray</author>
</book>
<header style="st3">
<user>3</user>
</header>
<book>
<isbn>0782140297</isbn>
<title>Coldfusion MX Developer's Handbook</title>
<author>Raymond Camden</author>
</book>
</root>
</cfxml>
<cfset bookTitle=xmlsearch(XMLFile,"//book/title/")>
<cfsavecontent variable="titles"><?xml version="1.0" encoding="UTF-8" ?>
<rootElem>
<cfloop array="#bookTitle#" index="idx">
<book>
<title><cfoutput>#idx.xmltext#</cfoutput></title>
</book>
</cfloop>
</rootElem>
</cfsavecontent>
<cfoutput>#xmlformat(titles)#</cfoutput>
North America
Europe, Middle East and Africa
Asia Pacific