# XML-RPC HOWTO

0.8.0, 2001-04-12
Eric
Kidd
Source Builders

    eric.kidd@pobox.com

And Other Contributors
浩一
野本
日本語翻訳

                hng@ps.ksky.ne.jp

2001
Eric Kidd

様々な言語でクライアントおよびサーバを実装するための XML-RPC の使用方法を述べます。例題のプログラムは Perl, Python, C, C++, Java, PHP および他の言語で示しています。Zope や KDE 2.0 についても 扱っています。XML-RPC のサポートはすべてのオペレーティングシステム で利用できます。

&legal.notice;

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

&legal.section;

# XML-RPC とは？

XML-RPC は HTTP 上 でリモート手続き呼び出しを行うための簡単で手軽な方法です。Perl, Java, Python, C, C++, PHP や多くの他のプログラミング言語で使用できま す。Unix と Windows, Macintosh 上で利用可能です。

Perl で書かれた短い XML-RPC クライアントを示します (Ken MacLeod の Frontier::Client を使用します)。

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

実行すると、このプログラムはリモートのサーバに接続し、州名を得 て、それを表示します (この例の州番号 41 は South Dakota のはずです)。

Python での同じプログラムです (これでは Fredrik Lundh の xmlrpclib を使います)。

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

以降の章では、様々な言語で XML-RPC クライアントおよびサーバの書 き方を学びます。

## どのように動作するのか

XML-RPC は Dave Winer の公式仕様書で詳細に説明さ れています。興味があるなら、是非ご覧になってください。簡潔で明解な 文書です。

通信する上で、XML-RPC の値は XML にエンコードされます -

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

上記は冗長ですが、簡単に圧縮できます。また、予想以上に速い です - Rick Blair の測定によれば、Hannes Wallnöfer の Java での実装を使うと XML-RPC 呼び出しの応答時間は 3 ミリ秒です。

## サポートされるデータの種別

XML-RPC は以下のデータの種別をサポートします。

`int`

  符号付 32 ビット整数

`string`

  ASCII 文字列で空バイトも許されます。(実際にはたくさんの XML-RPC の実装が Unicode をサポートしています。XML の基本機 能に感謝。)

`boolean`

  真か偽のどちらか

`double`

  倍精度浮動小数点実数 (実際にはいくつかの実装で使えない かもしれません)

`dateTime.iso8601`

  日付と時刻。残念ながら、XML-RPC はタイムゾーンの使用を 禁止しているので、これはほとんど役に立ちません。

`base64`

  任意長の生のバイナリデータ - 通信上 Base64 を使用して エンコードされます。とても役立ちます (けれどもいくつかの実装 では 0 バイトのデータ受信が行えません)。

`array`

  値の一次元配列。個々の値はどんな種別でもかまいません

`struct`

  キーと値の集まり。キーは文字列です - 値はどんな種別 でもかまいません。

## XML-RPC の歴史

XML-RPC は、先行する二つのプロトコルから着想を得ています。そ の一つは、anonymous RPC であり、これは Dave Winer により設計され、 過去に DaveNet でのエッセイとして発表されたものです (XML-RPC サー バが `/RPC2` 下にインストールされることが多いの はこのためです)。もう一つの、より重要な着想は、SOAP プロトコルの初 期ドラフトによるものです。

より詳しい XML-RPC の歴史という文書を Dave Winer が提供してくれてい ます。この文書では、XML-RPC と SOAP との関係についても説明されてい ます。

# XML-RPC 対 他のプロトコル

リモート手続き呼び出しは XML-RPC が唯一の方法ではありません。 人気のある他のプロトコルには CORBA, DCOM, SOAP などがあります。各 プロトコルには長所と短所があります。

この章での意見には、(著者の) 明らかな偏見も含まれています。ど うか、その点を考慮してお読みください。

## XML-RPC 対 CORBA

CORBA は人気のあ るプロトコルで、分散型オブジェクト指向アプリケーション向けに書かれ ています。一般的に複数の層を持つエンタープライズアプリケーションで 使用されます。最近では、アプリケーション間通信用にも Gnome プロジェクトによって選定 されています。

CORBA は多くのベンダーやたくさんのフリーソフトウェアプロジェ クトにより、よくサポートされています。CORBA は Java, C++ とうまく 動作し、多くの他の言語からも利用可能です。さらに CORBA は優れた interface definition language (IDL) を提供 し、読みやすいオブジェクト指向 API を定義できるようにします。

残念なことに、CORBA はとても複雑です。学習曲線は急勾配となっ ていて、実装するのに非常な努力を必要とし、かなり高度なクライアン トを必要とします。分散型ウェブアプリケーションよりもエンタープラ イズやデスクトップアプリケーションに一番適しています。

## XML-RPC 対 DCOM

DCOM は CORBA に対する Microsoft の答えです。すでに COM コン ポーネントを使用していて Microsoft 以外のシステムとやり取りする必 要がなければ、素晴らしいものです。そうでなければ、あまり役に立たな いでしょう。

## XML-RPC 対 SOAP

SOAP はとて も XML-RPC に似ています。XML 文書のまま、HTTP 上で整列した手続き呼 び出しを行う動作も似ています。残念ながら SOAP は仕様の確定に悩んで いるように見えます。

SOAP は元々 UserLand, DevelopMentor, Microsoft の共同制作に より作成されました。最初の公のリリースは基本的にネームスペースと長 いエレメント名を持つ XML-RPC でした。しかしその後 SOAP は W3C ワー キンググループに引き継がれました。

残念なことに、ワーキンググループは SOAPにとても多くの不可解 な機能の追加を行っています。この文書の執筆時点で、SOAP は XML スキーム、エミュレーション、奇妙な複合構造体および配列、そしてカス タムタイプをサポートしています。加えて、いくつもの SOAP の外部仕様 の実装も定義されています。

基本的に XML-RPC が好きであるけれどもっとたくさんの機能を持っ たプロトコルを望む場合、SOAP を調査するといいでしょう。 :-)

# 一般的な XML-RPC インターフェース

いくつかの XML-RPC サーバはビルトインメソッドを提供します。そ れらは XML-RPC それ自身のものではありませんが、とても便利な追加機能 です。

## イントロスペクション - サーバの API を掘り出す

Edd Dumbill は次のメソッドの組みを提案し ました。

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

サーバがこれらのメソッドをサポートする場合、あるドキュメンテー ションを印字するためにサーバへ問い合わせができます -

    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

これらのメソッドは PHP および C、Microsoft .NET で書かれたサー バによりサポートされています。部分的なイントロスペクションのサポー トは最近になって UserLand Frontier にも組み込まれています。Perl お よび Python, Java 用のイントロスペクションのサポートは XML-RPC Hacks のページで入手できます。どうぞ、遠慮なくイ ントロスペクションのサポートを他の XML-RPC サーバに追加してくださ い！

様々なクライアント側のツール (ドキュメンテーション、ラッパー 生成等等) も XML-RPC Hacks のページで見つけられます。

## Boxcarring - 同時に複数の要求を送る

多くのファンクションコールをする XML-RPC クライアントを書い ているなら、インターネットのバックボーンのレーテンシー (待ち時間) が短いおかげで、応答時間がかなり速いことを気づくかもしれません。い くつかのサーバは次の機能を使うことで複数の要求を一括処理 (batching) できます。

    array system.multicall (array calls)

追加情報は system.multicall RFC より得てください。

現在、このメソッドは C および UserLand Frontier で書かれたサー バでサポートされています。Python および Perl で書かれたサーバは XML-RPC Hacks のページにあるプログラムを利用できます。

# API の事例 - `sumAndDifference`

XML-RPC のデモをするために、可能な限り多くの言語で以下に示しま す。

    struct sample.sumAndDifference (int x, int y)

この関数は引き数として二つの整数を受け取って、二つのエレメント を持つ XML-RPC `<struct(構造体)>` を戻します -

`sum`

  二つの整数の和

`difference`

  二つの整数の差

実用的なものではありませんが、立派な例題になっています :-)

この関数 (や他のもの) は URL `http://xmlrpc-c.sourceforge.net/api/sample.php` を 利用しています (この URL はブラウザでは何もできず、XML-RPC クライア ントで利用できます)。

# Perl での XML-RPC の使い方

Ken MacLeod は Perl 用 XML-RPC を実装しています。彼の Frontier::RPC モジュールは彼のウェブサイトもしくは CPAN を通じて入手できます。

Frontier::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'

(ウィンドウ環境やルート権限の無い場合、わずかに違った手順とな るでしょう。詳細は Perl の文書を参考にしてください。)

## Perl クライアント

次のプログラムは Perl から XML-RPC サーバのコールの方法を示 します。

    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";

## 独立型 Perl サーバ

次のプログラムは Perl での XML-RPC サーバの書き方を示します。

    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: $!";

## CGI ベースの Perl サーバ

`Frontier::RPC2` は CGI ベースサーバ用のサ ポートは本来備えられていません。しかし大丈夫、 必要なほとんどの機能は用意されています。

次のプログラムコードを `sumAndDifference.cgi` として、ウェブサーバの `cgi-bin` ディレクトリに保存してください (Unix システム上で、`chmod +x sumAndDifference.cgi` と 入力し、実行属性を与える必要があるでしょう)。

    #!/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;
    }

あなた自身の CGI スクリプトにユーティリティルーチンをコピー してもかまいません。

# Python での XML-RPC の使い方

Fredrik Lundh は優れたPython 用 XML-RPC ライブラリを提供しています。

インストールするために、最新版をダウンロードしてください。 `*.py` ファイルを個人の Python プログラムとして、 個人のディレクトリに突っ込んでも、システムの Python ディレクトリにイ ンストールしてもかまいません。

RedHat 6.2 のユーザは次のように入力します。

    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/'

上記では、Python に二つの `*.py` をコンパイ ルさせるために、それらを `import` しています。他の プラットフォームでは Python の文書を参考にしてください。

さら多くの Python での例に関しては、O'Reilly network の XML-RPC: It Works Both Ways の記事をみてください。

## Python クライアント

次のプログラムは Python から XML-RPC サーバのコールの方法を 示します。

    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']

# C および C++ での XML-RPC の使い方

C/C++ 用 XML-RPC のコピーを得るには、xmlrpc-c のウェブサイトを 見てください。

RPM 形式ですべてのものをダウンロードすることも、ソースから自分 で環境を構築することもできます。

## C クライアント

次のプログラムコードを `getSumAndDifference.c` としてファイルに保存し てください。

    #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;
    }

コンパイルするための入力を示します -

    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

あなたのシステムの C コンパイラの名前が `gcc` ではないかもしれないので、実際の入力ではそ れを代える必要があるかもしれません。

## C++ クライアント

次のプログラムコードを `getSumAndDifference2.cc` としてファイルに保存 してください。

    #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;
    }

コンパイルするための入力を示します -

    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

この作業のために、かなり最近の C++ コンパイラが必要となりま す。

## 代替クラス (Proxy Class) での C++ クライアント

XML-RPC サーバがイントロスペクション API をサポートしているなら、自動的に そのサーバ用の C++ 代替クラスを生成できます。代替クラスを生成する ためには、次のコマンドを入力してその出力をファイルに保存してくださ い。

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

これは `sample` で始まるすべてのメソッド用 のラッパーが含まれている `SampleProxy` と名づけら れた代替クラスを生成します。あなたが望む方法でこのクラスを修正して もかまいません。

## CGI ベースの C サーバ

次のプログラムコードを `sumAndDifference.c` としてファイルに保存してく ださい。

    #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();
    }

コンパイルするための入力を示します -

    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

これが終了したら、`sumAndDifference.cgi` をウェブサーバの `cgi-bin` ディレクトリにコピー してください。

# Java での XML-RPC の使い方

Hannes Wallnöfer は Java 用 XML-RPC の優れた実装を提供しています。

インストールは、配布物をダウンロードして、unzip して、 `CLASSPATH` に `*.jar` ファイルを追 加します。Unix システム上で、次の入力によりこの作業が行えます。

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

## Java クライアント

次のプログラムコードを `JavaClient.java` としてファイルに保存してくだ さい。

    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());
            }
        }
    }

## 独立型 Java サーバ

次のプログラムコードを `JavaServer.java` としてファイルに保存してくだ さい。

    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());
            }
        }
    }

# PHP での XML-RPC の使い方

Edd Dumbill は PHP 用 XML-RPC を実装しています。UsefulInc XML-RPC ウェブサイトからダウンロードできます。

配布物をインストールするには、それを解凍して、 `xmlrpc.inc` と `xmlrpcs.inc` をあなたの PHP スクリプトが入っているのと同じディレクトリにコピーし ます。

## PHP クライアント

次のスクリプトはウェブページの中に XML-RPC コールを組み込む 方法を示します。

    <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>

あなたのウェブサーバが PHP スクリプトを実行しない場合、追加 情報を得るために PHP のウェブサイトを見てください。

## PHP サーバ

次のスクリプトは PHP を利用した XML-RPC サーバの実装の方法を 示します。

    <?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)));
    ?>

あなたは通常、 `http://localhost/path/sumAndDifference.php` のよ うなものを呼び出すでしょう。

# Microsoft .NET での XML-RPC の使い方

Charles Cook はこの HOWTO 用の優れた新しい章を執筆中です。草稿 はオンラインで見られます。そのページが姿を消したら、Linux Documentation Project で XML-RPC HOWTO の新版 を探してください。

# Ruby での XML-RPC の使い方

(XML-RPC HOWTO のこの章は Michael Neumann が気前よく 提供してくれました。)

Ruby はオブジェ クト指向スクリプト言語です。既に日本では多くの愛好者がおり、他所でも 人気が出つつあります。

Ruby で XML-RPC を使うには、初めに吉田正人の xmlparser モジュー ル (James Clark の expat parser 用ラッパー) をインストールしなければ なりません。これは Ruby Application Archive で見つけられます。

そして次のコマンドを使って xmlrpc4r をインストールしなければなりません。

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

## Ruby クライアント

単純な Ruby クライアントを示します -

    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}"

## Ruby サーバ

単純な Ruby サーバを示します -

    require "xmlrpc/server"

    s = XMLRPC::CGIServer.new

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

    s.serve

また、次のように書くこともできます。

    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

どちらのサーバも独立型で実行するには、プログラムの二行目を

    s = XMLRPC::Server.new(8080)

に書きかえてください。

# 独自的な言語での XML-RPC の使い方

XML-RPC の実装は以下に示す独自的なプログラミング言語および環境 で利用できます。

## K での XML-RPC の使い方

(XML-RPC HOWTO のこの章は Christian Langreiter が 気前よく提供してくれました。)

K は会計処理およびデー タベース開発で使われる言語です。K 用 XML-RPC をインストールするに は Kx のウェブサイトからダウンロードします。解凍してあなたの .k プログラムを保持しているディレクトリにファイルをコピーします。

短いクライアントを示します -

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

そしてサーバを示します -

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

さらに多くの例が配布物の中にあります。

# XML-RPC サポートが組み込まれたアプリケーション

いくつかの一般的な Linux アプリケーションは XML-RPC のサポート をしています。これらは既に他のところで説明がされているので、ここでは 主にその記事へのポインタを示します。

## Zope

Zope での XML-RPC の使用に関する記事は次に示すウェブから入 手できます。

- Jon Udell による Zope での XML-RPC プログラミング

- UserLand.Com の Zope XML-RPC

## KDE 2.0

KDE 2.0 は Kurt Ganroth の kxmlrpc デーモンを含み、デーモンは XML-RPC を使った KDE アプリケーションのためのお膳立てをします。

Python で書かれた短いアプリケーションの例があります。それは kxmlrpc へ接続する、 KDE の住所録を操作する、KDE トレーダを検索するといった方法を示しま す。

あなたがその他に記事やプログラムの例を持っている場合、 を見てください。私達は KDE を記述する上でもっと多くの情報を持ちたいと思っています。

# この文書について

この文書は Linux Documentation Project に所蔵されています。Dave Winer および様々な XML-RPC ライブラリのすべての管理者に感謝します。

## この文書の新版

この文書の新版は Linux Documentation Project のウェブサイトで入手できます。

また次のフォーマットでも提供されています。 PDF, gzipped HTML および ASCII text。

## XML-RPC HOWTO の寄稿者

Ruby に関する章は Michael Neumann (neumann AT s-direktnet DOT de) により寄稿されました。K に関する章は Christian Langreiter (c DOT langreiter AT synerge DOT at) により寄稿されました。

[訳注：上記の名前の後の () 内はメールアドレスを示しています。 「AT」は「@」、「DOT」は「.」に置きかえて、空白を除去すればメール アドレスが得られます。]

寄稿者はその章の始めに記入されています。

## 他の情報の提出

別の言語や環境でのクライアントやサーバの例を持っている場合、 この文書に追加したいととても思ってます。新しいエントリを追加するた めに、次に示す情報が必要です。

- XML-RPC を使用した実装の URL

- インストール手順

- 完全な実行できるプログラム

- 必要ならコンパイル手順

文書に記載してもかまわない E-mail アドレス - 例えば xmlrpc-c-devel メーリングリスト もしくは、直接の Eric Kidd。

情報をお待ちしています！

# 日本語訳について

日本語訳は Linux Japanese FAQ Project が行いました。 翻訳に関するご意見は JF プロジェクト <JF@linux.or.jp> 宛に連絡 してください。

## 0.8.0j

翻訳:

  野本 浩一 hng@ps.ksky.ne.jp

校正:

  - 千旦 裕司さん ysenda@pop01.odn.ne.jp

  - 山田 慎也さん trueheart@anet.ne.jp