XML-RPC HOWTO

Eric Kidd

Source Builders

<eric.kidd@pobox.com>

And Other Contributors

{_ - {|

            <hng@ps.ksky.ne.jp>
          

Copyright ? 2001 Eric Kidd

0.8.0, 2001-04-12

Revision History
Revision 0.8.0                           2001-04-12
Updated section on common interfaces. Added pointer to XML-RPC.Net
information.
Revision 0.7.0                           2001-04-03
Added section on C++ proxy classes.
Revision 0.6.0                           2001-02-02
Added sections on Ruby, K and common interfaces.
Revision 0.5.0                           2001-01-23
Initial version.

lXȌŃNCAgуT[o邽߂ XML-RPC ̎gp@
qׂ܂B̃vO Perl, Python, C, C++, Java, PHP ё
̌ŎĂ܂BZope  KDE 2.0 ɂĂĂ܂BXML-RPC
̃T|[gׂ͂ẴIy[eBOVXeŗpł܂B



Table of Contents
1. Legal Notice
2. XML-RPC Ƃ́H

    2.1. ǂ̂悤ɓ삷̂
    2.2. T|[gf[^̎
    2.3. XML-RPC ̗j

3. XML-RPC Α̃vgR

    3.1. XML-RPC  CORBA
    3.2. XML-RPC  DCOM
    3.3. XML-RPC  SOAP

4. ʓI XML-RPC C^[tF[X

    4.1. CgXyNV - T[o API @o
    4.2. Boxcarring - ɕ̗v𑗂

5. API ̎ - sumAndDifference
6. Perl ł XML-RPC ̎g

    6.1. Perl NCAg
    6.2. Ɨ^ Perl T[o
    6.3. CGI x[X Perl T[o

7. Python ł XML-RPC ̎g

    7.1. Python NCAg

8. C  C++ ł XML-RPC ̎g

    8.1. C NCAg
    8.2. C++ NCAg
    8.3. փNX (Proxy Class) ł C++ NCAg
    8.4. CGI x[X C T[o

9. Java ł XML-RPC ̎g

    9.1. Java NCAg
    9.2. Ɨ^ Java T[o

10. PHP ł XML-RPC ̎g

    10.1. PHP NCAg
    10.2. PHP T[o

11. Microsoft .NET ł XML-RPC ̎g
12. Ruby ł XML-RPC ̎g

    12.1. Ruby NCAg
    12.2. Ruby T[o

13. ƎIȌł XML-RPC ̎g

    13.1. K ł XML-RPC ̎g

14. XML-RPC T|[ggݍ܂ꂽAvP[V

    14.1. Zope
    14.2. KDE 2.0

15. ̕ɂ

    15.1. ̐̕V
    15.2. XML-RPC HOWTO ̊e
    15.3. ̏̒o

16. {ɂ

1. Legal Notice

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License <http://
www.fsf.org/copyleft/fdl.html>, Version 1.1 or any later version
published by the Free Software Foundation with no Invariant Sections,
no Front-Cover Texts, and no Back-Cover Texts. You may obtain a copy of
the GNU Free Documentation License from the Free Software Foundation by
visiting their Web site <http://www.fsf.org/> or by writing to: Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.

This manual contains short example programs ("the Software").
Permission is hereby granted, free of charge, to any person obtaining a
copy of the Software, to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following condition:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.



2. XML-RPC Ƃ́H

XML-RPC <http://www.xmlrpc.com/>  HTTP Ń[g葱Ăяos
߂̊ȒPŎyȕ@łBPerl, Java, Python, C, C++, PHP ⑽
̃vO~OŎgpł܂BUnix  Windows, Macintosh ŗ
p\łB

Perl ŏꂽZ XML-RPC NCAg܂ (Ken MacLeod 
Frontier::Client <http://bitsko.slc.ut.us/~ken/xml-rpc/> gp܂)
B

use Frontier::Client;
$server = Frontier::Client->new(url => 'http://betty.userland.com/RPC2');
$name = $server->call('examples.getStateName', 41);
print "$name\n";

sƁÃvO̓[g̃T[oɐڑAB𓾂āA
\܂ (̗̏Bԍ 41  South Dakota ̂͂ł)B

Python ł̓vOł (ł Fredrik Lundh  xmlrpclib
<http://www.pythonware.com/products/xmlrpc/> g܂)B

python> import xmlrpclib
python> server = xmlrpclib.Server("http://betty.userland.com/RPC2")
python> server.examples.getStateName(41)
'South Dakota'

ȍ~̏͂ł́AlXȌ XML-RPC NCAgуT[ȍw
т܂B



2.1. ǂ̂悤ɓ삷̂

XML-RPC  Dave Winer ̌dl <http://www.xmlrpc.com/spec>ŏڍׂ
Ă܂BȂA񂲗ɂȂĂBȌŖ
ȕłB

ʐMŁAXML-RPC ̒l XML ɃGR[h܂ -

<methodCall>
  <methodName>sample.sumAndDifference</methodName>
  <params>
    <param><value><int>5</int></value></param>
    <param><value><int>3</int></value></param>
  </params>
</methodCall>

L͏璷łAȒPɈkł܂B܂A\zȏɑł - Rick
Blair ̑ɂ΁AHannes Walln fer  Java ł̎g XML-RPC
ĂяỏԂ 3 ~błB



2.2. T|[gf[^̎

XML-RPC ͈ȉ̃f[^̎ʂT|[g܂B

int

    t 32 rbg

string

    ASCII ŋoCg܂B(ۂɂ͂ XML-RPC 
     Unicode T|[gĂ܂BXML ̊{@\ɊӁB)

boolean

    ^Ûǂ炩

double

    {x_ (ۂɂ͂̎ŎgȂ܂
    )

dateTime.iso8601

    tƎBcOȂAXML-RPC ̓^C][̎gp֎~Ă
    ̂ŁA͂قƂǖɗ܂B

base64

    CӒ̐̃oCif[^ - ʐM Base64 gpăGR[h
    ܂BƂĂ𗧂܂ (ǂ̎ł 0 oCg̃f[^
    Ms܂)B

array

    l̈ꎟzBX̒l͂ǂȎʂł܂܂

struct

    L[ƒl̏W܂BL[͕ł - l͂ǂȎʂł܂܂
    B



2.3. XML-RPC ̗j

XML-RPC ́As̃vgR璅z𓾂Ă܂B̈́A
anonymous RPC łA Dave Winer ɂ݌vAߋ DaveNet
ł̃GbZC <http://davenet.userland.com/1998/02/27/rpcOverHttpViaXml>
ƂĔ\ꂽ̂ł (XML-RPC T[o /RPC2 ɃCXg[
Ƃ̂͂̂߂ł)B́AdvȒźASOAP vg
Ȑhtgɂ̂łB

ڂ XML-RPC ̗j <http://www.xmlrpc.com/stories/
storyReader$555>Ƃ Dave Winer 񋟂ĂĂ܂B̕
ł́AXML-RPC  SOAP Ƃ̊֌WɂĂĂ܂B



3. XML-RPC Α̃vgR

[g葱Ăяo XML-RPC B̕@ł͂܂BlĈ
̃vgRɂ CORBA, DCOM, SOAP Ȃǂ܂BevgRɂ͒
ƒZ܂B

̏͂ł̈ӌɂ́A(҂) 炩ȕΌ܂܂Ă܂BǂA
_lĂǂ݂B



3.1. XML-RPC  CORBA

CORBA <http://www.corba.org/> ͐lĈvgRŁAU^IuWF
NgwAvP[VɏĂ܂BʓIɕ̑wG
^[vCYAvP[VŎgp܂Bŋ߂ł́AAvP[V
ԒʐMpɂ Gnome <http://www.gnome.org/> vWFNgɂđI肳
Ă܂B

CORBA ͑̃x_[₽̃t[\tgEFAvWFNgɂ
A悭T|[gĂ܂BCORBA  Java, C++ Ƃ܂삵Ȃ
̌ꂩp\łB CORBA ͗Dꂽ interface definition
language (IDL) 񋟂Aǂ݂₷IuWFNgw API `ł
ɂ܂B

cOȂƂɁACORBA ͂ƂĂGłBwKȐ͋}zƂȂĂāA
̂ɔȓw͂KvƂAȂ荂xȃNCAgKvƂ܂
BU^EFuAvP[VG^[vCYfXNgbvAv
P[VɈԓKĂ܂B



3.2. XML-RPC  DCOM

DCOM <http://www.microsoft.com/com/tech/DCOM.asp>  CORBA ɑ΂
Microsoft ̓łBł COM R|[lggpĂ Microsoft
ȊÕVXeƂ肷KvȂ΁Af炵̂łB
Ȃ΁A܂ɗȂł傤B



3.3. XML-RPC  SOAP

SOAP <http://www.w3.org/TR/SOAP/> ͂ƂĂ XML-RPC ɎĂ܂BXML 
̂܂܁AHTTP Ő񂵂葱ĂяosĂ܂BcO
 SOAP ͎dl̊mɔYł悤Ɍ܂B

SOAP ͌X UserLand, DevelopMentor, Microsoft ̋ɂ쐬
܂Bŏ̌̃[X͊{IɃl[Xy[XƒGg
 XML-RPC łB̌ SOAP  W3C [LOO[vɈ
p܂B

cOȂƂɁA[LOO[v SOAPɂƂĂ̕sȋ@\̒ǉ
sĂ܂B̎̕M_ŁASOAP  XML XL[AG~[
VAȕ\̂єzAăJX^^CvT|[g
܂BāA SOAP ̊Odl̎`Ă܂B

{I XML-RPC Dł邯ǂƂ̋@\vgR
]ޏꍇASOAP 𒲍Ƃł傤B :-)



4. ʓI XML-RPC C^[tF[X

 XML-RPC T[o̓rgC\bh񋟂܂B
XML-RPC ꎩĝ̂ł͂܂񂪁AƂĂ֗Ȓǉ@\łB



4.1. CgXyNV - T[o API @o

Edd Dumbill ͎̃\bh̑g݂ <http://xmlrpc.usefulinc.com/doc
/reserved.html>܂B

array system.listMethods ()
string system.methodHelp (string methodName)
array system.methodSignature (string methodName)

T[õ\bhT|[gꍇAhLe[V
󎚂邽߂ɃT[o֖₢킹ł܂ -

import xmlrpclib
server = xmlrpclib.Server("http://xmlrpc-c.sourceforge.net/api/sample.php")
for method in server.system.listMethods():
    print method
    print server.system.methodHelp(method)
    print

̃\bh PHP  CAMicrosoft .NET ŏꂽT[oɂ
T|[gĂ܂BIȃCgXyNṼT|[g͍ŋ߂ɂ
 UserLand Frontier ɂgݍ܂Ă܂BPerl  Python, Java
p̃CgXyNṼT|[g XML-RPC Hacks <http://
xmlrpc-c.sourceforge.net/hacks.php> ̃y[Wœł܂BǂA
ȂCgXyNṼT|[g𑼂 XML-RPC T[oɒǉĂ
I

lXȃNCAg̃c[ (hLe[VAbp[)
 XML-RPC Hacks ̃y[WŌ܂B



4.2. Boxcarring - ɕ̗v𑗂

̃t@NVR[ XML-RPC NCAgĂȂA
C^[lbg̃obN{[̃[eV[ (҂) ZŁA
ԂȂ葬ƂCÂ܂B̃T[o͎
@\gƂŕ̗vꊇ (batching) ł܂B

array system.multicall (array calls)

ǉ system.multicall RFC <http://www.xmlrpc.com/discuss/
msgReader$1208> 蓾ĂB

݁Ã\bh C  UserLand Frontier ŏꂽT[oŃT|
[gĂ܂BPython  Perl ŏꂽT[o XML-RPC Hacks
<http://xmlrpc-c.sourceforge.net/hacks.php> ̃y[WɂvO
pł܂B



5. API ̎ - sumAndDifference

XML-RPC ̃f邽߂ɁA\Ȍ葽̌ňȉɎ܂B

struct sample.sumAndDifference (int x, int y)

̊֐͈Ƃē̐󂯎āA̃Gg
XML-RPC <struct(\)> ߂܂ -

sum

    ̘̐a

difference

    ̐̍

pIȂ̂ł͂܂񂪁AhȗɂȂĂ܂ :-)

̊֐ (⑼̂)  URL http://xmlrpc-c.sourceforge.net/api/
sample.php 𗘗pĂ܂ ( URL ̓uEUł͉łAXML-RPC
NCAgŗpł܂)B



6. Perl ł XML-RPC ̎g

Ken MacLeod  Perl p XML-RPC Ă܂Bނ Frontier::RPC 
W[͔ނ̃EFuTCg <http://bitsko.slc.ut.us/~ken/xml-rpc/>
 CPAN <http://www.cpan.org/> ʂēł܂B

Frontier::RPC CXg[ɂ́AWIȂŃpbP[W_E
[hăRpC܂ -

bash$ gunzip -c Frontier-RPC-0.07b1.tar.gz | tar xvf -
bash$ cd Frontier-RPC-0.07b1
bash$ perl Makefile.PL
bash$ make
bash$ make test
bash$ su -c 'make install'

(EBhE⃋[g̖ꍇA킸Ɉ菇ƂȂł傤
Bڍׂ Perl ̕QlɂĂB)



6.1. Perl NCAg

̃vO Perl  XML-RPC T[õR[̕@܂B

use Frontier::Client;

# Make an object to represent the XML-RPC server.
$server_url = 'http://xmlrpc-c.sourceforge.net/api/sample.php';
$server = Frontier::Client->new(url => $server_url);

# Call the remote server and get our result.
$result = $server->call('sample.sumAndDifference', 5, 3);
$sum = $result->{'sum'};
$difference = $result->{'difference'};

print "Sum: $sum, Difference: $difference\n";



6.2. Ɨ^ Perl T[o

̃vO Perl ł XML-RPC T[ȍ܂B

use Frontier::Daemon;

sub sumAndDifference {
    my ($x, $y) = @_;
    return {'sum' => $x + $y, 'difference' => $x - $y};
}

# Call me as http://localhost:8080/RPC2
$methods = {'sample.sumAndDifference' => \&sumAndDifference};
Frontier::Daemon->new(LocalPort => 8080, methods => $methods)
    or die "Couldn't start HTTP server: $!";



6.3. CGI x[X Perl T[o

Frontier::RPC2  CGI x[XT[op̃T|[g͖{Ă܂
BvAKvȂقƂǂ̋@\͗pӂĂ܂B

̃vOR[h sumAndDifference.cgi ƂāAEFuT[o
cgi-bin fBNgɕۑĂ (Unix VXeŁAchmod +x
sumAndDifference.cgi Ɠ͂As^Kvł傤)B

#!/usr/bin/perl -w

use strict;
use Frontier::RPC2;

sub sumAndDifference {
    my ($x, $y) = @_;
    return {'sum' => $x + $y, 'difference' => $x - $y};
}

process_cgi_call({'sample.sumAndDifference' => \&sumAndDifference});

#==========================================================================
#  CGI Support
#==========================================================================
#  Simple CGI support for Frontier::RPC2. You can copy this into your CGI
#  scripts verbatim, or you can package it into a library.
#  (Based on xmlrpc_cgi.c by Eric Kidd <http://xmlrpc-c.sourceforge.net/>.)

# Process a CGI call.
sub process_cgi_call ($) {
    my ($methods) = @_;

    # Get our CGI request information.
    my $method = $ENV{'REQUEST_METHOD'};
    my $type = $ENV{'CONTENT_TYPE'};
    my $length = $ENV{'CONTENT_LENGTH'};

    # Perform some sanity checks.
    http_error(405, "Method Not Allowed") unless $method eq "POST";
    http_error(400, "Bad Request") unless $type eq "text/xml";
    http_error(411, "Length Required") unless $length > 0;

    # Fetch our body.
    my $body;
    my $count = read STDIN, $body, $length;
    http_error(400, "Bad Request") unless $count == $length;

    # Serve our request.
    my $coder = Frontier::RPC2->new;
    send_xml($coder->serve($body, $methods));
}

# Send an HTTP error and exit.
sub http_error ($$) {
    my ($code, $message) = @_;
    print <<"EOD";
Status: $code $message
Content-type: text/html

<title>$code $message</title>
<h1>$code $message</h1>
<p>Unexpected error processing XML-RPC request.</p>
EOD
    exit 0;
}

# Send an XML document (but don't exit).
sub send_xml ($) {
    my ($xml_string) = @_;
    my $length = length($xml_string);
    print <<"EOD";
Status: 200 OK
Content-type: text/xml

EOD
    # We want precise control over whitespace here.
    print $xml_string;
}

Ȃg CGI XNvgɃ[eBeB[`Rs[Ă܂
܂B



7. Python ł XML-RPC ̎g

Fredrik Lundh ͗DꂽPython p XML-RPC Cu <http://
www.pythonware.com/products/xmlrpc/>񋟂Ă܂B

CXg[邽߂ɁAŐVł_E[hĂB *.py t@C
l Python vOƂāAl̃fBNgɓ˂łA
VXe Python fBNgɃCXg[Ă܂܂B

RedHat 6.2 ̃[Û͎悤ɓ͂܂B

bash$ mkdir xmlrpclib-0.9.8
bash$ cd xmlrpclib-0.9.8
bash$ unzip ../xmlrpc-0.9.8-990621.zip
bash$ python
python> import xmlrpclib
python> import xmlrpcserver
python> Control-D
bash$ su -c 'cp *.py *.pyc /usr/lib/python1.5/'

Lł́APython ɓ *.py RpC邽߂ɁA
import Ă܂B̃vbgtH[ł Python ̕QlɂĂ
B

瑽 Python ł̗ɊւẮAO'Reilly network  XML-RPC: It
Works Both Ways <http://www.oreillynet.com/pub/a/python/2001/01/17/
xmlrpcserver.html> ̋L݂ĂB



7.1. Python NCAg

̃vO Python  XML-RPC T[õR[̕@܂B

import xmlrpclib

# Create an object to represent our server.
server_url = 'http://xmlrpc-c.sourceforge.net/api/sample.php';
server = xmlrpclib.Server(server_url);

# Call the server and get our result.
result = server.sample.sumAndDifference(5, 3)
print "Sum:", result['sum']
print "Difference:", result['difference']



8. C  C++ ł XML-RPC ̎g

C/C++ p XML-RPC ̃Rs[𓾂ɂ́Axmlrpc-c ̃EFuTCg <http://
xmlrpc-c.sourceforge.net>ĂB

RPM `łׂĂ̂̂_E[h邱ƂA\[X玩Ŋ
\z邱Ƃł܂B



8.1. C NCAg

̃vOR[h getSumAndDifference.c Ƃăt@CɕۑĂ
B

#include <stdio.h>
#include <xmlrpc.h>
#include <xmlrpc_client.h>

#define NAME       "XML-RPC getSumAndDifference C Client"
#define VERSION    "0.1"
#define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php"

void die_if_fault_occurred (xmlrpc_env *env)
{
    /* Check our error-handling environment for an XML-RPC fault. */
    if (env->fault_occurred) {
        fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
                env->fault_string, env->fault_code);
        exit(1);
    }
}

int main (int argc, char** argv)
{
    xmlrpc_env env;
    xmlrpc_value *result;
    xmlrpc_int32 sum, difference;

    /* Start up our XML-RPC client library. */
    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
    xmlrpc_env_init(&env);

    /* Call our XML-RPC server. */
    result = xmlrpc_client_call(&env, SERVER_URL,
                                "sample.sumAndDifference", "(ii)",
                                (xmlrpc_int32) 5,
                                (xmlrpc_int32) 3);
    die_if_fault_occurred(&env);

    /* Parse our result value. */
    xmlrpc_parse_value(&env, result, "{s:i,s:i,*}",
                       "sum", &sum,
                       "difference", &difference);
    die_if_fault_occurred(&env);

    /* Print out our sum and difference. */
    printf("Sum: %d, Difference: %d\n", (int) sum, (int) difference);

    /* Dispose of our result value. */
    xmlrpc_DECREF(result);

    /* Shutdown our XML-RPC client library. */
    xmlrpc_env_clean(&env);
    xmlrpc_client_cleanup();

    return 0;
}

RpC邽߂̓͂܂ -

bash$ CLIENT_CFLAGS=`xmlrpc-c-config libwww-client --cflags`
bash$ CLIENT_LIBS=`xmlrpc-c-config libwww-client --libs`
bash$ gcc $CLIENT_CFLAGS -o getSumAndDifference getSumAndDifference.c $CLIENT_LIBS

Ȃ̃VXe C RpC̖O gcc ł͂ȂȂ̂ŁA
ۂ̓͂ł͂ウKv邩܂B



8.2. C++ NCAg

̃vOR[h getSumAndDifference2.cc Ƃăt@Cɕۑ
B

#include <iostream.h>
#include <XmlRpcCpp.h>

#define NAME       "XML-RPC getSumAndDifference C++ Client"
#define VERSION    "0.1"
#define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php"

static void get_sum_and_difference () {

    // Build our parameter array.
    XmlRpcValue param_array = XmlRpcValue::makeArray();
    param_array.arrayAppendItem(XmlRpcValue::makeInt(5));
    param_array.arrayAppendItem(XmlRpcValue::makeInt(3));

    // Create an object to resprent the server, and make our call.
    XmlRpcClient server (SERVER_URL);
    XmlRpcValue result = server.call("sample.sumAndDifference", param_array);

    // Extract the sum and difference from our struct.
    XmlRpcValue::int32 sum = result.structGetValue("sum").getInt();
    XmlRpcValue::int32 diff = result.structGetValue("difference").getInt();

    cout << "Sum: " << sum << ", Difference: " << diff << endl;
}

int main (int argc, char **argv) {

    // Start up our client library.
    XmlRpcClient::Initialize(NAME, VERSION);

    // Call our client routine, and watch out for faults.
    try {
        get_sum_and_difference();
    } catch (XmlRpcFault& fault) {
        cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
             << ": " << fault.getFaultString() << endl;
        XmlRpcClient::Terminate();
        exit(1);
    }

    // Shut down our client library.
    XmlRpcClient::Terminate();
    return 0;
}

RpC邽߂̓͂܂ -

bash$ CLIENT_CFLAGS=`xmlrpc-c-config c++ libwww-client --cflags`
bash$ CLIENT_LIBS=`xmlrpc-c-config c++ libwww-client --libs`
bash$ c++ $CLIENT_CFLAGS -o getSumAndDifference2 getSumAndDifference2.cc $CLIENT_LIBS

̍Ƃ̂߂ɁAȂŋ߂ C++ RpCKvƂȂ܂B



8.3. փNX (Proxy Class) ł C++ NCAg

XML-RPC T[oCgXyNV API T|[gĂȂAI
ɂ̃T[op C++ փNX𐶐ł܂BփNX𐶐邽
ɂ́ÃR}h͂Ă̏o͂t@CɕۑĂB

bash$ xml-rpc-api2cpp \
> http://xmlrpc-c.sourceforge.net/api/sample.php sample SampleProxy

 sample Ŏn܂邷ׂẴ\bhp̃bp[܂܂Ă
SampleProxy ƖÂꂽփNX𐶐܂BȂ]ޕ@ł
̃NXCĂ܂܂B



8.4. CGI x[X C T[o

̃vOR[h sumAndDifference.c Ƃăt@CɕۑĂ
B

#include <xmlrpc.h>
#include <xmlrpc_cgi.h>

xmlrpc_value *
sumAndDifference (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data)
{
    xmlrpc_int32 x, y;

    /* Parse our argument array. */
    xmlrpc_parse_value(env, param_array, "(ii)", &x, &y);
    if (env->fault_occurred)
        return NULL;

    /* Return our result. */
    return xmlrpc_build_value(env, "{s:i,s:i}",
                              "sum", x + y,
                              "difference", x - y);
}

int main (int argc, char **argv)
{
    /* Set up our CGI library. */
    xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS);

    /* Install our only method (with a method signature and a help string). */
    xmlrpc_cgi_add_method_w_doc("sample.sumAndDifference",
                                &sumAndDifference, NULL,
                                "S:ii", "Add and subtract two integers.");

    /* Call the appropriate method. */
    xmlrpc_cgi_process_call();

    /* Clean up our CGI library. */
    xmlrpc_cgi_cleanup();
}

RpC邽߂̓͂܂ -

bash$ CGI_CFLAGS=`xmlrpc-c-config cgi-server --cflags`
bash$ CGI_LIBS=`xmlrpc-c-config cgi-server --libs`
bash$ gcc $CGI_CFLAGS -o sumAndDifference.cgi sumAndDifference.c $CGI_LIBS

ꂪIAsumAndDifference.cgi EFuT[o cgi-bin fB
NgɃRs[ĂB



9. Java ł XML-RPC ̎g

Hannes Walln fer  Java p XML-RPC ̗Dꂽ <http://helma.at/
hannes/xmlrpc/>񋟂Ă܂B

CXg[́Azz_E[hāAunzip āA CLASSPATH 
*.jar t@Cǉ܂BUnix VXeŁA̓͂ɂ肱̍Ƃ
s܂B

bash$ unzip xmlrpc-java.zip
bash$ cd xmlrpc-java/lib
bash$ CLASSPATH=`pwd`/openxml-1.2.jar:`pwd`/xmlrpc.jar:$CLASSPATH



9.1. Java NCAg

̃vOR[h JavaClient.java Ƃăt@CɕۑĂ
B

import java.util.Vector;
import java.util.Hashtable;
import helma.xmlrpc.*;

public class JavaClient {

    // The location of our server.
    private final static String server_url =
        "http://xmlrpc-c.sourceforge.net/api/sample.php";

    public static void main (String [] args) {
        try {

            // Create an object to represent our server.
            XmlRpcClient server = new XmlRpcClient(server_url);

            // Build our parameter list.
            Vector params = new Vector();
            params.addElement(new Integer(5));
            params.addElement(new Integer(3));

            // Call the server, and get our result.
            Hashtable result =
                (Hashtable) server.execute("sample.sumAndDifference", params);
            int sum = ((Integer) result.get("sum")).intValue();
            int difference = ((Integer) result.get("difference")).intValue();

            // Print out our result.
            System.out.println("Sum: " + Integer.toString(sum) +
                               ", Difference: " +
                               Integer.toString(difference));

        } catch (XmlRpcException exception) {
            System.err.println("JavaClient: XML-RPC Fault #" +
                               Integer.toString(exception.code) + ": " +
                               exception.toString());
        } catch (Exception exception) {
            System.err.println("JavaClient: " + exception.toString());
        }
    }
}



9.2. Ɨ^ Java T[o

̃vOR[h JavaServer.java Ƃăt@CɕۑĂ
B

import java.util.Hashtable;
import helma.xmlrpc.*;

public class JavaServer {

    public JavaServer () {
        // Our handler is a regular Java object. It can have a
        // constructor and member variables in the ordinary fashion.
        // Public methods will be exposed to XML-RPC clients.
    }

    public Hashtable sumAndDifference (int x, int y) {
        Hashtable result = new Hashtable();
        result.put("sum", new Integer(x + y));
        result.put("difference", new Integer(x - y));
        return result;
    }

    public static void main (String [] args) {
        try {

            // Invoke me as <http://localhost:8080/RPC2>.
            WebServer server = new WebServer(8080);
            server.addHandler("sample", new JavaServer());

        } catch (Exception exception) {
            System.err.println("JavaServer: " + exception.toString());
        }
    }
}



10. PHP ł XML-RPC ̎g

Edd Dumbill  PHP p XML-RPC Ă܂BUsefulInc XML-RPC EF
uTCg <http://xmlrpc.usefulinc.com/>_E[hł܂B

zzCXg[ɂ́A𓀂āA xmlrpc.inc 
xmlrpcs.inc Ȃ PHP XNvgĂ̂ƓfBNg
Rs[܂B



10.1. PHP NCAg

̃XNvg̓EFuy[W̒ XML-RPC R[gݍޕ@
B

<html>
<head>
<title>XML-RPC PHP Demo</title>
</head>
<body>
<h1>XML-RPC PHP Demo</h1>

<?php
include 'xmlrpc.inc';

// Make an object to represent our server.
$server = new xmlrpc_client('/api/sample.php',
                            'xmlrpc-c.sourceforge.net', 80);

// Send a message to the server.
$message = new xmlrpcmsg('sample.sumAndDifference',
                         array(new xmlrpcval(5, 'int'),
                               new xmlrpcval(3, 'int')));
$result = $server->send($message);

// Process the response.
if (!$result) {
    print "<p>Could not connect to HTTP server.</p>";
} elseif ($result->faultCode()) {
    print "<p>XML-RPC Fault #" . $result->faultCode() . ": " .
        $result->faultString();
} else {
    $struct = $result->value();
    $sumval = $struct->structmem('sum');
    $sum = $sumval->scalarval();
    $differenceval = $struct->structmem('difference');
    $difference = $differenceval->scalarval();
    print "<p>Sum: " . htmlentities($sum) .
        ", Difference: " . htmlentities($difference) . "</p>";
}
?>

</body></html>

Ȃ̃EFuT[o PHP XNvgsȂꍇAǉ𓾂邽
߂ PHP ̃EFuTCg <http://www.php.net/>ĂB



10.2. PHP T[o

̃XNvg PHP 𗘗p XML-RPC T[o̎̕@܂B

<?php
include 'xmlrpc.inc';
include 'xmlrpcs.inc';

function sumAndDifference ($params) {

    // Parse our parameters.
    $xval = $params->getParam(0);
    $x = $xval->scalarval();
    $yval = $params->getParam(1);
    $y = $yval->scalarval();

    // Build our response.
    $struct = array('sum' => new xmlrpcval($x + $y, 'int'),
                    'difference' => new xmlrpcval($x - $y, 'int'));
    return new xmlrpcresp(new xmlrpcval($struct, 'struct'));
}

// Declare our signature and provide some documentation.
// (The PHP server supports remote introspection. Nifty!)
$sumAndDifference_sig = array(array('struct', 'int', 'int'));
$sumAndDifference_doc = 'Add and subtract two numbers';

new xmlrpc_server(array('sample.sumAndDifference' =>
                        array('function' => 'sumAndDifference',
                              'signature' => $sumAndDifference_sig,
                              'docstring' => $sumAndDifference_doc)));
?>

Ȃ͒ʏA http://localhost/path/sumAndDifference.php ̂悤Ȃ
Ăяoł傤B



11. Microsoft .NET ł XML-RPC ̎g

Charles Cook ͂ HOWTO p̗DꂽV͂MłBe̓I
C <http://www.cookcomputing.com/misc/howto.txt>Ō܂B̃y
[WpALinux Documentation Project  XML-RPC HOWTO ̐V
<http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html> TĂ
B



12. Ruby ł XML-RPC ̎g

(XML-RPC HOWTO ̂̏͂ Michael Neumann CO悭񋟂Ă܂
B)

Ruby <http://www.ruby-lang.org/> ̓IuWFNgwXNvgłB
ɓ{ł͑̈D҂AłlCo܂B

Ruby  XML-RPC gɂ́A߂ɋgcl xmlparser W[
(James Clark  expat parser pbp[) CXg[Ȃ΂Ȃ
B Ruby Application Archive <http://www.ruby-lang.org/en/
raa.html> Ō܂B

Ď̃R}hg xmlrpc4r <http://www.s-direktnet.de/
homepages/neumann/xmlrpc4r/index.html> CXg[Ȃ΂Ȃ܂
B

bash$ tar -xvzf xmlrpc4r-1_2.tar.gz
bash$ cd xmlrpc4r-1_2
bash$ su root -c "ruby install.rb"



12.1. Ruby NCAg

P Ruby NCAg܂ -

require "xmlrpc/client"

# Make an object to represent the XML-RPC server.
server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")

# Call the remote server and get our result
result = server.call("sample.sumAndDifference", 5, 3)

sum = result["sum"]
difference = result["difference"]

puts "Sum: #{sum}, Difference: #{difference}"



12.2. Ruby T[o

P Ruby T[o܂ -

require "xmlrpc/server"

s = XMLRPC::CGIServer.new

s.add_hanlder("sample.sumAndDifference") do |a,b|
  { "sum" => a + b, "difference" => a - b }
end

s.serve

܂Â悤ɏƂł܂B

require "xmlrpc/server"

s = XMLRPC::CGIServer.new

class MyHandler
  def sumAndDifference(a, b)
    { "sum" => a + b, "difference" => a - b }
  end
end

s.add_handler("sample", MyHandler.new)
s.serve

ǂ̃T[oƗ^Ŏsɂ́AvO̓sڂ

s = XMLRPC::Server.new(8080)

ɏĂB



13. ƎIȌł XML-RPC ̎g

XML-RPC ͈̎ȉɎƎIȃvO~Oꂨъŗp
܂B



13.1. K ł XML-RPC ̎g

(XML-RPC HOWTO ̂̏͂ Christian Langreiter CO悭񋟂Ă
B)

K <http://www.kx.com/> ͉vуf[^x[XJŎg錾
BK p XML-RPC CXg[ɂ Kx ̃EFuTCg <http://
www.langreiter.com/k/kxr>_E[h܂B𓀂ĂȂ .k v
OێĂfBNgɃt@CRs[܂B

ZNCAg܂ -

\l kxr
server:("localhost";"/cgi-bin/sumAndDifference.cgi");
.kxr.c[server;"sumAndDifference";2 3]

ăT[o܂ -

\l kxrsc
.kxr.sm: ,("sumAndDifference";{.((`sum;+/x);(`difference;-/x))})

ɑ̗Ⴊzz̒ɂ܂B



14. XML-RPC T|[ggݍ܂ꂽAvP[V

̈ʓI Linux AvP[V XML-RPC ̃T|[gĂ
܂B͊ɑ̂ƂŐĂ̂ŁAł͎ɂ̋L
ւ̃|C^܂B



14.1. Zope

Zope ł XML-RPC ̎gpɊւL͎ɎEFuł܂B

 E Jon Udell ɂ Zope ł XML-RPC vO~O <http://
    www.byte.com/column/BYT19991021S0014>

 E UserLand.Com  Zope XML-RPC <http://linux.userland.com/stories/
    storyReader$18>



14.2. KDE 2.0

KDE 2.0  Kurt Ganroth  kxmlrpc f[ <http://
kdecvs.stud.fh-heilbronn.de/cvsweb/kdebase/kxmlrpc/>܂݁Af[
XML-RPC g KDE AvP[V̂߂̂VĂ܂B

Python ŏꂽZAvP[V̗ <http://
kdecvs.stud.fh-heilbronn.de/cvsweb/kdebase/kxmlrpc/test/testxmlrpc.py?
rev=1.6&content-type=text/x-cvsweb-markup>܂B kxmlrpc 
ڑA KDE ̏Z^𑀍삷AKDE g[_Ƃ@
܂B

Ȃ̑ɋLvO̗ĂꍇA Section 15.3> 
ĂBB KDE LqłƑ̏Ǝv
Ă܂B



15. ̕ɂ

̕ Linux Documentation Project <http://www.linuxdoc.org/> ɏ
Ă܂BDave Winer їlX XML-RPC CûׂĂ̊
҂Ɋӂ܂B



15.1. ̐̕V

̐̕Vł Linux Documentation Project <http://www.linuxdoc.org/
HOWTO/XML-RPC-HOWTO/index.html> ̃EFuTCgœł܂B

܂̃tH[}bgł񋟂Ă܂B PDF <http://www.ibiblio.org/
pub/Linux/docs/HOWTO/other-formats/pdf/XML-RPC-HOWTO.pdf>, gzipped HTML
<http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html/
XML-RPC-HOWTO-html.tar.gz>  ASCII text <http://www.ibiblio.org/
pub/Linux/docs/HOWTO/XML-RPC-HOWTO>B



15.2. XML-RPC HOWTO ̊e

Ruby Ɋւ͂ Michael Neumann (neumann AT s-direktnet DOT de) ɂ
e܂BK Ɋւ͂ Christian Langreiter (c DOT langreiter
AT synerge DOT at) ɂe܂B

[󒍁FL̖Ǒ () ̓[AhXĂ܂BuATv́u
@vAuDOTv́u.vɒuāA󔒂΃[AhX
܂B]

e҂͂̏͂̎n߂ɋLĂ܂B



15.3. ̏̒o

ʂ̌ł̃NCAgT[o̗ĂꍇA̕
ǉƂƂĂvĂ܂BVGgǉ邽߂ɁAɎ
񂪕KvłB

 E XML-RPC gp URL

 E CXg[菇

 E SȎsłvO

 E KvȂRpC菇

ɋLڂĂ܂Ȃ E-mail AhX - Ⴆ xmlrpc-c-devel [
OXg <http://xmlrpc-c.sourceforge.net/lists.php> ́A
 Eric Kidd <mailto:eric.kidd@pobox.com>B

҂Ă܂I



16. {ɂ

{ Linux Japanese FAQ Project s܂B|Ɋւ邲ӌ
 JF vWFNg <JF@linux.or.jp> ɘAĂB

0.8.0j

|:

    {_ <hng@ps.ksky.ne.jp>

Z:

      UTi <ysenda@pop01.odn.ne.jp>

      RcT炳 <trueheart@anet.ne.jp>

