XML-RPC web service requests
An XML-RPC web service takes its call parameters as an XML document rather than
as a set of URL variables. To conduct a transaction with an XML-RPC web service,
create a properly formatted XML message and send it to the web service using the
HTTP POST
method. In addition, you should set the Content-Type
header for
the request so that the server treats the request data as XML.
The following example illustrates how to use the same web service call shown in the REST example, but this time as an XML-RPC service:
import flash.events.Event;
import flash.events.ErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
public function xmlRPCRequest():void
{
//Create the XML-RPC document
var xmlRPC:XML = <methodCall>
<methodName></methodName>
<params>
<param>
<value>
<struct/>
</value>
</param>
</params>
</methodCall>;
xmlRPC.methodName = "test.echo";
//Add the method parameters
var parameters:Object = new Object();
parameters.api_key = "123456ABC";
parameters.message = "Able was I, ere I saw Elba.";
for( var propertyName:String in parameters )
{
xmlRPC..struct.member[xmlRPC..struct.member.length + 1] =
<member>
<name>{propertyName}</name>
<value>
<string>{parameters[propertyName]}</string>
</value>
</member>;
}
//Create the HTTP request object
var request:URLRequest = new URLRequest( "http://service.example.com/xml-rpc/" );
request.method = URLRequestMethod.POST;
request.cacheResponse = false;
request.requestHeaders.push(new URLRequestHeader("Content-Type", "application/xml"));
request.data = xmlRPC;
//Initiate the request
requestor = new URLLoader();
requestor.dataFormat = URLLoaderDataFormat.TEXT;
requestor.addEventListener( Event.COMPLETE, xmlRPCRequestComplete );
requestor.addEventListener( IOErrorEvent.IO_ERROR, xmlRPCRequestError );
requestor.addEventListener( SecurityErrorEvent.SECURITY_ERROR, xmlRPCRequestError );
requestor.load( request );
}
private function xmlRPCRequestComplete( event:Event ):void
{
trace( XML(event.target.data).toXMLString() );
}
private function xmlRPCRequestError( error:ErrorEvent ):void
{
trace( "An error occurred: " + error );
}
WebKit in AIR doesn't support E4X syntax, so the method used to create the XML document in the previous example does not work in JavaScript code. Instead, you must use the DOM methods to create the XML document or create the document as a string and use the JavaScript DOMParser class to convert the string to XML.
The following example uses DOM methods to create an XML-RPC message and an XMLHttpRequest to conduct the web service transaction:
<html>
<head>
<title>XML-RPC web service request</title>
<script type="text/javascript">
function makeRequest()
{
var requestDisplay = document.getElementById( "request" );
var resultDisplay = document.getElementById( "result" );
var request = {};
request.URL = "http://services.example.com/xmlrpc/";
request.method = "test.echo";
request.HTTPmethod = "POST";
request.parameters = {};
request.parameters.api_key = "123456ABC";
request.parameters.message = "Able was I ere I saw Elba.";
var requestMessage = formatXMLRPC( request );
xmlhttp = new XMLHttpRequest();
xmlhttp.open( request.HTTPmethod, request.URL, true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
resultDisplay.innerText = xmlhttp.responseText;
}
}
xmlhttp.send( requestMessage );
requestDisplay.innerText = xmlToString( requestMessage.documentElement );
}
//Formats a request as XML-RPC document
function formatXMLRPC( request )
{
var xmldoc = document.implementation.createDocument( "", "", null );
var root = xmldoc.createElement( "methodCall" );
xmldoc.appendChild( root );
var methodName = xmldoc.createElement( "methodName" );
var methodString = xmldoc.createTextNode( request.method );
methodName.appendChild( methodString );
root.appendChild( methodName );
var params = xmldoc.createElement( "params" );
root.appendChild( params );
var param = xmldoc.createElement( "param" );
params.appendChild( param );
var value = xmldoc.createElement( "value" );
param.appendChild( value );
var struct = xmldoc.createElement( "struct" );
value.appendChild( struct );
for( var property in request.parameters )
{
var member = xmldoc.createElement( "member" );
struct.appendChild( member );
var name = xmldoc.createElement( "name" );
var paramName = xmldoc.createTextNode( property );
name.appendChild( paramName )
member.appendChild( name );
var value = xmldoc.createElement( "value" );
var type = xmldoc.createElement( "string" );
value.appendChild( type );
var paramValue = xmldoc.createTextNode( request.parameters[property] );
type.appendChild( paramValue )
member.appendChild( value );
}
return xmldoc;
}
//Returns a string representation of an XML node
function xmlToString( rootNode, indent )
{
if( indent == null ) indent = "";
var result = indent + "<" + rootNode.tagName + ">\n";
for( var i = 0; i < rootNode.childNodes.length; i++)
{
if(rootNode.childNodes.item( i ).nodeType == Node.TEXT_NODE )
{
result += indent + " " + rootNode.childNodes.item( i ).textContent + "\n";
}
}
if( rootNode.childElementCount > 0 )
{
result += xmlToString( rootNode.firstElementChild, indent + " " );
}
if( rootNode.nextElementSibling )
{
result += indent + "</" + rootNode.tagName + ">\n";
result += xmlToString( rootNode.nextElementSibling, indent );
}
else
{
result += indent +"</" + rootNode.tagName + ">\n";
}
return result;
}
</script>
</head>
<body onload="makeRequest()">
<h1>Request:</h1>
<pre id="request"></pre>
<h1>Result:</h1>
<pre id="result"></pre>
</body>
</html>