Copy link to clipboard
Copied
Hi,
How can I read xml file using web services?
Here is my cfc web services: (I just want to see how to read the xml file)
<cfcomponent>
<cffunction name="getBooks" access="remote" returntype="string" output="no">
<cfargument name="xmlObject" type="xml" required="yes" >
<cfset BookResponse = "">
<cfset var arrIndx = "">
<cftry>
<cfloop from="1" to="#ArrayLen(arguments.xmlObject.XmlChildren)#" index="arrIndx">
<cfset BookResponse= arguments.xmlObject.XmlChildren[arrIndx].XmlName>
</cfloop>
<cfcatch type="any">
<cfset BookResponse= "#cfcatch.message# #cfcatch.detail#">
</cfcatch>
</cftry>
<cfreturn BookResponse>
</cffunction>
</cfcomponent>
Here my code to test the web services:
1. Define the xml
<!--- Setup some XML to work with --->
<cfsavecontent variable="XMLFile"><?xml version="1.0"?>
<root>
<header>
<user>1</user>
</header>
<book>
<isbn>0321330110</isbn>
<title>Macromedia ColdFusion MX 7 Certified Developer Study Guide</title>
<author>Ben Forta</author>
</book>
<header>
<user>2</user>
</header>
<book>
<isbn>0596004206</isbn>
<title>Learning XML, Second Edition</title>
<author>Erik Ray</author>
</book>
<header>
<user>3</user>
</header>
<book>
<isbn>0782140297</isbn>
<title>Coldfusion MX Developer's Handbook</title>
<author>Raymond Camden</author>
</book>
</root>
</cfsavecontent>
2.Invoke the web services
<cfinvoke
method="getBooks"
returnvariable="rawXMLBookList"
webservice="http://localhost/Hoteleria/webServices/books.cfc?wsdl">
<cfinvokeargument name="xmlObject" value="#XMLFile#">
</cfinvoke>
<!---<cfset XMLDocResult = XmlParse(rawXMLBookList)>
<cfdump var="#XMLDocResult#">--->
<cfdump var="#rawXMLBookList#' >
3. Error: Element XMLOBJECT.XMLCHILDREN is undefined in ARGUMENTS.
I try also using XMLParse without luck.
Any ideas?
Thanks
Sorry about that. It did work for me!
What about doing it on the basis of strings, as follows:
books.cfc
<cfcomponent>
<cffunction name="getAuthors" access="remote" returntype="string" output="yes">
<cfargument name="xmlString" type="string" required="yes" >
<cfset var xmlObject = "">
<cfset var rootChildren = "">
<cfset var authors = "">
<cfset var arrIndx = "">
<cfxml variable="xmlObject"><cfoutput>#arguments.xmlString#</cfoutput></cfxml>
<cfset rootChildren = xmlObje
...Copy link to clipboard
Copied
Looks like is not passing the XML doc.
I try this in my function: <cfset BookResponse = #xmlObject#>
Just to see if I can see the XML, I am getting this: [#document: null]
Any ideas?
Copy link to clipboard
Copied
Here is the solution:
http://www.bennadel.com/blog/1612-AxisFault-ColdFusion-Web-Services-And-XML-Data-Types.htm
Best,
Copy link to clipboard
Copied
There are few things you can improve, for example, using cfxml to pass an XML object, rather than cfsavecontent which passes a string. The following ilustrates this and other points:
books.cfc
<cfcomponent>
<cffunction name="getAuthors" access="remote" returntype="string" output="no">
<cfargument name="xmlObject" type="xml" required="yes" >
<cfset var authors = "">
<cfset var arrIndx = "">
<cftry>
<cfloop from="1" to="#ArrayLen(arguments.xmlObject.XmlRoot["root"].XmlChildren)#" index="arrIndx">
<!--- 'Author' elements are in 'book'. The 'book' elements are even-numbered --->
<cfif arrIndx mod 2 is 0>
<cfset authors = authors & chr(10) & chr(13) & arguments.xmlObject.XmlRoot["root"].XmlChildren[arrIndx].author.XmlText>
</cfif>
</cfloop>
<cfcatch type="any">
<cfset authors = "#cfcatch.message# #cfcatch.detail#">
</cfcatch>
</cftry>
<cfreturn authors>
</cffunction>
</cfcomponent>
testPage.cfm
<!--- Setup some XML to work with --->
<cfxml variable="XMLFile"><root>
<header>
<user>1</user>
</header>
<book>
<isbn>0321330110</isbn>
<title>Macromedia ColdFusion MX 7 Certified Developer Study Guide</title>
<author>Ben Forta</author>
</book>
<header>
<user>2</user>
</header>
<book>
<isbn>0596004206</isbn>
<title>Learning XML, Second Edition</title>
<author>Erik Ray</author>
</book>
<header>
<user>3</user>
</header>
<book>
<isbn>0782140297</isbn>
<title>Coldfusion MX Developer's Handbook</title>
<author>Raymond Camden</author>
</book>
</root>
</cfxml>
<!---Invoke the web services--->
<cfinvoke
method="getAuthors"
returnvariable="authorList"
webservice="http://localhost/Hoteleria/webServices/books.cfc?wsdl">
<cfinvokeargument name="xmlObject" value="#XMLFile#">
</cfinvoke>
<cfdump var="#authorList#" >
Copy link to clipboard
Copied
Thanks for you reply and help.
I try your suggestion, i got this error:
An error occured while Parsing an XML document. Content is not allowed in prolog.
If I change the function parameter type from xml to any, it pass but i get this error:
Element XMLOBJECT.XMLROOT is undefined in ARGUMENTS.
Any ideas?
Copy link to clipboard
Copied
How does your cfargument line look like?
Copy link to clipboard
Copied
I am using your example files. I have CF9.
Thanks!
Copy link to clipboard
Copied
Odd. Just as a test, what happens when you drop the arguments scope, like this
<cfloop from="1" to="#ArrayLen(xmlObject.XmlRoot["root"].XmlChildren)#" index="arrIndx">
<!--- 'Author' elements are in 'book'. The 'book' elements are even-numbered --->
<cfif arrIndx mod 2 is 0>
<cfset authors = authors & chr(10) & chr(13) & xmlObject.XmlRoot["root"].XmlChildren[arrIndx].author.XmlText>
</cfif>
</cfloop
Copy link to clipboard
Copied
I am back to this XML issue.
I am getting this:
Element XMLROOT is undefined in XMLOBJECT.
Something is not clicking here.
Any ideas?
Thanks for your help!
Copy link to clipboard
Copied
Sorry about that. It did work for me!
What about doing it on the basis of strings, as follows:
books.cfc
<cfcomponent>
<cffunction name="getAuthors" access="remote" returntype="string" output="yes">
<cfargument name="xmlString" type="string" required="yes" >
<cfset var xmlObject = "">
<cfset var rootChildren = "">
<cfset var authors = "">
<cfset var arrIndx = "">
<cfxml variable="xmlObject"><cfoutput>#arguments.xmlString#</cfoutput></cfxml>
<cfset rootChildren = xmlObject.xmlRoot.xmlChildren>
<cftry>
<cfloop from="1" to="#ArrayLen(rootChildren)#" index="arrIndx">
<!--- 'Author' elements are in 'book'. The 'book' elements are even-numbered --->
<cfif arrIndx mod 2 is 0>
<cfset authors = authors & chr(10) & chr(13) & rootChildren[arrIndx].author.XmlText>
</cfif>
</cfloop>
<cfcatch type="any">
<cfset authors = "#cfcatch.message# #cfcatch.detail#">
</cfcatch>
</cftry>
<cfreturn authors>
</cffunction>
</cfcomponent>
testPage.cfm
<!--- Setup XML string to work with --->
<cfsavecontent variable="XMLFile"><root>
<header>
<user>1</user>
</header>
<book>
<isbn>0321330110</isbn>
<title>Macromedia ColdFusion MX 7 Certified Developer Study Guide</title>
<author>Ben Forta</author>
</book>
<header>
<user>2</user>
</header>
<book>
<isbn>0596004206</isbn>
<title>Learning XML, Second Edition</title>
<author>Erik Ray</author>
</book>
<header>
<user>3</user>
</header>
<book>
<isbn>0782140297</isbn>
<title>Coldfusion MX Developer's Handbook</title>
<author>Raymond Camden</author>
</book>
</root>
</cfsavecontent>
<!---Invoke the web services--->
<cfinvoke
method="getAuthors"
returnvariable="authorList"
webservice="http://localhost/Hoteleria/webServices/books.cfc?wsdl">
<cfinvokeargument name="xmlString" value="#XMLFile#">
</cfinvoke>
<cfdump var="#authorList#" >
Copy link to clipboard
Copied
This solution work BKBK, Thanks!
Now if it is not much to ask. I add a general node at the top of the xml like:
<general>
<accountUser>234</accountUser>
</general>
How can I go to the node "accountUser", change the value and return the whole xml file with this new value updated?
Best,
Copy link to clipboard
Copied
jfb00 wrote:
This solution work BKBK, Thanks!
Now if it is not much to ask. I add a general node at the top of the xml like:
<general>
<accountUser>234</accountUser>
</general>
How can I go to the node "accountUser", change the value and return the whole xml file with this new value updated?
<!--- The XML document object --->
<cfxml variable="XMLObject"><root>
<general>
<accountUser>234</accountUser>
</general>
<header>
<user>1</user>
</header>
<book>
<isbn>0321330110</isbn>
<title>Macromedia ColdFusion MX 7 Certified Developer Study Guide</title>
<author>Ben Forta</author>
</book>
<header>
<user>2</user>
</header>
<book>
<isbn>0596004206</isbn>
<title>Learning XML, Second Edition</title>
<author>Erik Ray</author>
</book>
<header>
<user>3</user>
</header>
<book>
<isbn>0782140297</isbn>
<title>Coldfusion MX Developer's Handbook</title>
<author>Raymond Camden</author>
</book>
</root>
</cfxml>
<cfset XMLObject.root.general.accountUser.xmlText = 567>
<cfdump var="#XMLObject#">
Copy link to clipboard
Copied
Thank you so much for your time and help!
Best,
Copy link to clipboard
Copied
How kind of you!
Copy link to clipboard
Copied
If the call to the web service continues to fail, then refresh the WSDL. The following code will refresh it:
<cfset serviceFactory = CreateObject("java", "coldfusion.server.ServiceFactory")>
<cfset rpcService = serviceFactory.XmlRpcService>
<cfset wsdl="http://localhost/Hoteleria/webServices/books.cfc?wsdl">
<cfset rpcService.refreshWebService(wsdl)>
Message was edited by: BKBK