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>