xmlrpc.clientXML-RPC client accessXML-RPC客户端访问

Source code: Lib/xmlrpc/client.py


XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP(S) as a transport. XML-RPC是一种远程过程调用方法,它使用通过HTTP(S)传递的XML作为传输。With it, a client can call methods with parameters on a remote server (the server is named by a URI) and get back structured data. 有了它,客户端可以在远程服务器上调用带有参数的方法(服务器由URI命名),并获取结构化数据。This module supports writing XML-RPC client code; it handles all the details of translating between conformable Python objects and XML on the wire.该模块支持编写XML-RPC客户端代码;它处理了在兼容的Python对象和XML之间转换的所有细节。

Warning警告

The xmlrpc.client module is not secure against maliciously constructed data. xmlrpc.client模块对恶意构建的数据不安全。If you need to parse untrusted or unauthenticated data see XML vulnerabilities.如果需要解析不受信任或未经身份验证的数据,请查看XML漏洞

Changed in version 3.5:版本3.5中更改: For HTTPS URIs, xmlrpc.client now performs all the necessary certificate and hostname checks by default.对于HTTPS URI,xmlrpc.client现在默认执行所有必要的证书和主机名检查。

classxmlrpc.client.ServerProxy(uri, transport=None, encoding=None, verbose=False, allow_none=False, use_datetime=False, use_builtin_types=False, *, headers=(), context=None)

A ServerProxy instance is an object that manages communication with a remote XML-RPC server. ServerProxy实例是一个管理与远程XML-RPC服务器通信的对象。The required first argument is a URI (Uniform Resource Indicator), and will normally be the URL of the server. 所需的第一个参数是URI(一致性资源指示符),通常是服务器的URL。The optional second argument is a transport factory instance; by default it is an internal SafeTransport instance for https: URLs and an internal HTTP Transport instance otherwise. 可选的第二个参数是一个传输工厂实例;默认情况下,它是https:URL的内部SafeTransport实例,否则是内部HTTPTransport实例。The optional third argument is an encoding, by default UTF-8. The optional fourth argument is a debugging flag.可选的第三个参数是编码,默认情况下为UTF-8。可选的第四个参数是调试标志。

The following parameters govern the use of the returned proxy instance. 以下参数控制返回的代理实例的使用。If allow_none is true, the Python constant None will be translated into XML; the default behaviour is for None to raise a TypeError. 如果allow_nonetrue,Python常量None将被转换为XML;默认行为是None引发TypeErrorThis is a commonly-used extension to the XML-RPC specification, but isn’t supported by all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a description. 这是XML-RPC规范的常用扩展,但并非所有客户端和服务器都支持;参阅http://ontosys.com/xml-rpc/extensions.php用于描述。The use_builtin_types flag can be used to cause date/time values to be presented as datetime.datetime objects and binary data to be presented as bytes objects; this flag is false by default. use_builtin_types标志可用于使日期/时间值被呈现为datetime.datetime对象,并且二进制数据被呈现为bytes对象;默认情况下,此标志为falsedatetime.datetime, bytes and bytearray objects may be passed to calls. The headers parameter is an optional sequence of HTTP headers to send with each request, expressed as a sequence of 2-tuples representing the header name and value. (e.g. [(‘Header-Name’, ‘value’)]). datetime.datetimebytesbytearray对象可以传递给调用。headers参数是随每个请求发送的可选HTTP标头序列,表示为表示标头名称和值的2元组序列。(例如[(‘Header-Name’, ‘value’)])。The obsolete use_datetime flag is similar to use_builtin_types but it applies only to date/time values.过时的use_datetime标志类似于use_builtin_types,但它仅适用于日期/时间值。

Changed in version 3.3:版本3.3中更改: The use_builtin_types flag was added.已添加use_builtin_types标志。

Changed in version 3.8:版本3.8中更改: The headers parameter was added.已添加headers参数。

Both the HTTP and HTTPS transports support the URL syntax extension for HTTP Basic Authentication: http://user:pass@host:port/path. HTTP和HTTPS传输都支持HTTP基本身份验证的URL语法扩展:http://user:pass@host:port/pathThe user:pass portion will be base64-encoded as an HTTP ‘Authorization’ header, and sent to the remote server as part of the connection process when invoking an XML-RPC method. user:pass部分将以base64编码为HTTP“Authorization”标头,并在调用XML-RPC方法时作为连接过程的一部分发送到远程服务器。You only need to use this if the remote server requires a Basic Authentication user and password. 仅当远程服务器需要基本身份验证用户和密码时,才需要使用此选项。If an HTTPS URL is provided, context may be ssl.SSLContext and configures the SSL settings of the underlying HTTPS connection.如果提供了HTTPS URL,则context可以是ssl.SSLContext,并配置底层HTTPS连接的SSL设置。

The returned instance is a proxy object with methods that can be used to invoke corresponding RPC calls on the remote server. 返回的实例是一个代理对象,其方法可用于在远程服务器上调用相应的RPC调用。If the remote server supports the introspection API, the proxy can also be used to query the remote server for the methods it supports (service discovery) and fetch other server-associated metadata.如果远程服务器支持内省API,则代理还可以用于查询远程服务器以获取其支持的方法(服务发现),并获取其他与服务器相关的元数据。

Types that are conformable (e.g. that can be marshalled through XML), include the following (and except where noted, they are unmarshalled as the same Python type):一致的类型(例如,可以通过XML进行编组的类型)包括以下内容(除非另有说明,否则它们被取消编组为相同的Python类型):

XML-RPC type

Python type

boolean

bool

int, i1, i2, i4, i8 or biginteger

int in range from -2147483648 to 2147483647. int的范围从-2147483648到2147483647。Values get the <int> tag.值得到<int>标记。

double or float

float. Values get the <double> tag.。值得到<double>标记。

string

str

array

list or tuple containing conformable elements. 包含一致元素的listtupleArrays are returned as lists.数组以lists形式返回。

struct

dict. Keys must be strings, values may be any conformable type. 。键必须是字符串,值可以是任何合适的类型。Objects of user-defined classes can be passed in; only their __dict__ attribute is transmitted.可以传入自定义类的对象;仅传输它们的__dict__属性。

dateTime.iso8601

DateTime or datetime.datetime. DateTimedatetime.datetimeReturned type depends on values of use_builtin_types and use_datetime flags.返回的类型取决于use_builtin_typesuse_datetime标志的值。

base64

Binary, bytes or bytearray. Returned type depends on the value of the use_builtin_types flag.返回的类型取决于use_builtin_types标志的值。

nil

The None constant. None常量。Passing is allowed only if allow_none is true.只有当allow_nonetrue时,才允许传递。

bigdecimal

decimal.Decimal. Returned type only.。仅返回类型。

This is the full set of data types supported by XML-RPC. 这是XML-RPC支持的全套数据类型。Method calls may also raise a special Fault instance, used to signal XML-RPC server errors, or ProtocolError used to signal an error in the HTTP/HTTPS transport layer. 方法调用还可能引发一个特殊的Fault实例,用于表示XML-RPC服务器错误,或ProtocolError,用于表示HTTP/HTTPS传输层中的错误。Both Fault and ProtocolError derive from a base class called Error. FaultProtocolError都派生自一个名为Error的基类。Note that the xmlrpc client module currently does not marshal instances of subclasses of built-in types.请注意,xmlrpc客户端模块当前不封送内置类型的子类的实例。

When passing strings, characters special to XML such as <, >, and & will be automatically escaped. 在传递字符串时,XML专用的字符(如<>&)将自动转义。However, it’s the caller’s responsibility to ensure that the string is free of characters that aren’t allowed in XML, such as the control characters with ASCII values between 0 and 31 (except, of course, tab, newline and carriage return); failing to do this will result in an XML-RPC request that isn’t well-formed XML. 但是,调用者有责任确保字符串中没有XML中不允许的字符,例如ASCII值在0到31之间的控制字符(当然,制表符、换行符和回车符除外);如果不这样做,将导致XML-RPC请求不是格式良好的XML。If you have to pass arbitrary bytes via XML-RPC, use bytes or bytearray classes or the Binary wrapper class described below.如果必须通过XML-RPC传递任意字节,请使用bytesbytearray类或下面描述的二进制包装器类。

Server is retained as an alias for ServerProxy for backwards compatibility. New code should use ServerProxy.Server保留为ServerProxy的别名,以实现向后兼容性。新代码应使用ServerProxy

Changed in version 3.5:版本3.5中更改: Added the context argument.添加了context参数。

Changed in version 3.6:版本3.6中更改: Added support of type tags with prefixes (e.g. ex:nil). 增加了对带前缀的类型标记的支持(例如,ex:nil)。Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: i1, i2, i8, biginteger, float and bigdecimal. 增加了对Apache XML-RPC实现中使用的其他类型(i1i2i8bigintegerfloatbigdecimal)进行解组的支持。See http://ws.apache.org/xmlrpc/types.html for a description.参阅http://ws.apache.org/xmlrpc/types.html用于描述。

See also

XML-RPC HOWTO

A good description of XML-RPC operation and client software in several languages. 用几种语言很好地描述了XML-RPC操作和客户端软件。Contains pretty much everything an XML-RPC client developer needs to know.几乎包含XML-RPC客户端开发人员需要了解的所有内容。

XML-RPC Introspection

Describes the XML-RPC protocol extension for introspection.描述用于内省的XML-RPC协议扩展。

XML-RPC Specification

The official specification.官方规范。

Unofficial XML-RPC Errata

Fredrik Lundh’s “unofficial errata, intended to clarify certain details in the XML-RPC specification, as well as hint at ‘best practices’ to use when designing your own XML-RPC implementations.”Fredrik Lundh的“非官方勘误表,旨在澄清XML-RPC规范中的某些细节,并提示在设计自己的XML-RPC实现时要使用的‘最佳实践’。”

ServerProxy Objects

A ServerProxy instance has a method corresponding to each remote procedure call accepted by the XML-RPC server. ServerProxy实例具有与XML-RPC服务器接受的每个远程过程调用相对应的方法。Calling the method performs an RPC, dispatched by both name and argument signature (e.g. the same method name can be overloaded with multiple argument signatures). 调用方法执行RPC,由名称和参数签名进行调度(例如,同一个方法名称可以重载多个参数签名)。The RPC finishes by returning a value, which may be either returned data in a conformant type or a Fault or ProtocolError object indicating an error.RPC通过返回一个值来完成,该值可以是一致类型的返回数据,也可以是指示错误的FaultProtocolError对象。

Servers that support the XML introspection API support some common methods grouped under the reserved system attribute:支持XML内省API的服务器支持在保留system属性下分组的一些常见方法:

ServerProxy.system.listMethods()

This method returns a list of strings, one for each (non-system) method supported by the XML-RPC server.此方法返回一个字符串列表,XML-RPC服务器支持的每个(非系统)方法一个字符串。

ServerProxy.system.methodSignature(name)

This method takes one parameter, the name of a method implemented by the XML-RPC server. It returns an array of possible signatures for this method. 此方法采用一个参数,即XML-RPC服务器实现的方法的名称。它返回此方法的一个可能签名数组。A signature is an array of types. The first of these types is the return type of the method, the rest are parameters.签名是一个类型数组。这些类型中的第一个是方法的返回类型,其余的是参数。

Because multiple signatures (ie. overloading) is permitted, this method returns a list of signatures rather than a singleton.因为允许多个签名(即重载),所以此方法返回一个签名列表,而不是单个签名。

Signatures themselves are restricted to the top level parameters expected by a method. For instance if a method expects one array of structs as a parameter, and it returns a string, its signature is simply “string, array”. 签名本身被限制为方法所期望的顶级参数。例如,如果一个方法期望一个结构数组作为参数,而它返回一个字符串,那么它的签名就是“string,array”。If it expects three integers and returns a string, its signature is “string, int, int, int”.如果它需要三个整数并返回一个字符串,则其签名为“string,int,int,整型”。

If no signature is defined for the method, a non-array value is returned. In Python this means that the type of the returned value will be something other than list.如果没有为该方法定义签名,则返回一个非数组值。在Python中,这意味着返回值的类型将不是list。

ServerProxy.system.methodHelp(name)

This method takes one parameter, the name of a method implemented by the XML-RPC server. 此方法采用一个参数,即XML-RPC服务器实现的方法的名称。It returns a documentation string describing the use of that method. 它返回一个描述该方法使用情况的文档字符串。If no such string is available, an empty string is returned. 如果没有这样的字符串可用,则返回一个空字符串。The documentation string may contain HTML markup.文档字符串可能包含HTML标记。

Changed in version 3.5:版本3.5中更改: Instances of ServerProxy support the context manager protocol for closing the underlying transport.ServerProxy的实例支持用于关闭底层传输的上下文管理器协议。

A working example follows. The server code:下面是一个工作示例。服务器代码:

from xmlrpc.server import SimpleXMLRPCServer
def is_even(n):
return n % 2 == 0

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(is_even, "is_even")
server.serve_forever()

The client code for the preceding server:前面服务器的客户端代码:

import xmlrpc.client
with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
print("3 is even: %s" % str(proxy.is_even(3)))
print("100 is even: %s" % str(proxy.is_even(100)))

DateTime Objects

classxmlrpc.client.DateTime

This class may be initialized with seconds since the epoch, a time tuple, an ISO 8601 time/date string, or a datetime.datetime instance. 此类可以使用自epoch以来的秒数、时间元组、ISO 8601时间/日期字符串或datetime.datetime实例进行初始化。It has the following methods, supported mainly for internal use by the marshalling/unmarshalling code:它有以下方法,主要由编组/解编组代码支持内部使用:

decode(string)

Accept a string as the instance’s new time value.接受一个字符串作为实例的新时间值。

encode(out)

Write the XML-RPC encoding of this DateTime item to the out stream object.将此DateTime项的XML-RPC编码写入out流对象。

It also supports certain of Python’s built-in operators through rich comparison and __repr__() methods.它还通过丰富的比较和__repr_()方法支持Python的某些内置运算符。

A working example follows. The server code:下面是一个工作示例。服务器代码:

import datetime
from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client
def today():
today = datetime.datetime.today()
return xmlrpc.client.DateTime(today)

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(today, "today")
server.serve_forever()

The client code for the preceding server:前面服务器的客户端代码:

import xmlrpc.client
import datetime
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")

today = proxy.today()
# convert the ISO8601 string to a datetime object
converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print("Today: %s" % converted.strftime("%d.%m.%Y, %H:%M"))

Binary Objects

classxmlrpc.client.Binary

This class may be initialized from bytes data (which may include NULs). 这个类可以从字节数据(可能包括NUL)初始化。The primary access to the content of a Binary object is provided by an attribute:Binary对象内容的主要访问由一个属性提供:

data

The binary data encapsulated by the Binary instance. Binary实例封装的二进制数据。The data is provided as a bytes object.数据以bytes对象的形式提供。

Binary objects have the following methods, supported mainly for internal use by the marshalling/unmarshalling code:对象具有以下方法,主要由编组/解编组代码支持内部使用:

decode(bytes)

Accept a base64 bytes object and decode it as the instance’s new data.接受一个base64bytes的对象,并将其解码为实例的新数据。

encode(out)

Write the XML-RPC base 64 encoding of this binary item to the out stream object.将此二进制项的XML-RPC base64编码写入out流对象。

The encoded data will have newlines every 76 characters as per RFC 2045 section 6.8, which was the de facto standard base64 specification when the XML-RPC spec was written.根据RFC 2045第6.8节,编码的数据将每76个字符有一行换行符,这是编写XML-RPC规范时事实上的标准base64规范。

It also supports certain of Python’s built-in operators through __eq__() and __ne__() methods.它还通过__eq__()__ne__()方法支持Python的某些内置运算符。

Example usage of the binary objects. We’re going to transfer an image over XMLRPC:二进制对象的示例用法。我们将通过XMLRPC传输图像:

from xmlrpc.server import SimpleXMLRPCServer
import xmlrpc.client
def python_logo():
with open("python_logo.jpg", "rb") as handle:
return xmlrpc.client.Binary(handle.read())

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(python_logo, 'python_logo')

server.serve_forever()

The client gets the image and saves it to a file:客户端获取图像并将其保存到一个文件中:

import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
handle.write(proxy.python_logo().data)

Fault Objects

classxmlrpc.client.Fault

A Fault object encapsulates the content of an XML-RPC fault tag. Fault objects have the following attributes:Fault对象封装XML-RPC故障标记的内容。故障对象具有以下属性:

faultCode

An int indicating the fault type.指示故障类型的int。

faultString

A string containing a diagnostic message associated with the fault.包含与故障相关联的诊断消息的字符串。

In the following example we’re going to intentionally cause a Fault by returning a complex type object. The server code:在下面的例子中,我们将通过返回一个复杂类型的对象来故意导致Fault。服务器代码:

from xmlrpc.server import SimpleXMLRPCServer
# A marshalling error is going to occur because we're returning a
# complex number
def add(x, y):
return x+y+0j

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(add, 'add')

server.serve_forever()

The client code for the preceding server:前面服务器的客户端代码:

import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
try:
proxy.add(2, 5)
except xmlrpc.client.Fault as err:
print("A fault occurred")
print("Fault code: %d" % err.faultCode)
print("Fault string: %s" % err.faultString)

ProtocolError Objects

classxmlrpc.client.ProtocolError

A ProtocolError object describes a protocol error in the underlying transport layer (such as a 404 ‘not found’ error if the server named by the URI does not exist). It has the following attributes:ProtocolError对象描述底层传输层中的协议错误(例如,如果URI命名的服务器不存在,则会出现404“未找到”错误)。它具有以下属性:

url

The URI or URL that triggered the error.触发错误的URI或URL。

errcode

The error code.错误代码。

errmsg

The error message or diagnostic string.错误消息或诊断字符串。

headers

A dict containing the headers of the HTTP/HTTPS request that triggered the error.一个dict,包含触发错误的HTTP/HTTPS请求的标头。

In the following example we’re going to intentionally cause a ProtocolError by providing an invalid URI:在以下示例中,我们将通过提供无效的URI来故意导致ProtocolError

import xmlrpc.client
# create a ServerProxy with a URI that doesn't respond to XMLRPC requests
proxy = xmlrpc.client.ServerProxy("http://google.com/")

try:
proxy.some_method()
except xmlrpc.client.ProtocolError as err:
print("A protocol error occurred")
print("URL: %s" % err.url)
print("HTTP/HTTPS headers: %s" % err.headers)
print("Error code: %d" % err.errcode)
print("Error message: %s" % err.errmsg)

MultiCall Objects

The MultiCall object provides a way to encapsulate multiple calls to a remote server into a single request 1.MultiCall对象提供了一种将对远程服务器的多个调用封装到单个请求1中的方法。

classxmlrpc.client.MultiCall(server)

Create an object used to boxcar method calls. 创建一个用于boxcar方法调用的对象。server is the eventual target of the call. 是通话的最终目标。Calls can be made to the result object, but they will immediately return None, and only store the call name and parameters in the MultiCall object. 可以对结果对象进行调用,但它们会立即返回None,并且只将调用名称和参数存储在MultiCall对象中。Calling the object itself causes all stored calls to be transmitted as a single system.multicall request. 调用对象本身会导致所有存储的调用作为单个system.multicall请求进行传输。The result of this call is a generator; iterating over this generator yields the individual results.这个调用的结果是一个生成器;对这个生成器进行迭代会产生单独的结果。

A usage example of this class follows. The server code:下面是这个类的用法示例。服务器代码:

from xmlrpc.server import SimpleXMLRPCServer
def add(x, y):
return x + y

def subtract(x, y):
return x - y

def multiply(x, y):
return x * y

def divide(x, y):
return x // y

# A simple server with simple arithmetic functions
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_multicall_functions()
server.register_function(add, 'add')
server.register_function(subtract, 'subtract')
server.register_function(multiply, 'multiply')
server.register_function(divide, 'divide')
server.serve_forever()

The client code for the preceding server:前面服务器的客户端代码:

import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:8000/")
multicall = xmlrpc.client.MultiCall(proxy)
multicall.add(7, 3)
multicall.subtract(7, 3)
multicall.multiply(7, 3)
multicall.divide(7, 3)
result = multicall()

print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % tuple(result))

Convenience Functions便利功能

xmlrpc.client.dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False)

Convert params into an XML-RPC request. or into a response if methodresponse is true. params转换为XML-RPC请求。如果methodresponsetrue,则转换为响应。params can be either a tuple of arguments or an instance of the Fault exception class. params可以是参数元组,也可以是Fault异常类的实例。If methodresponse is true, only a single value can be returned, meaning that params must be of length 1. 如果methodresponsetrue,则只能返回一个值,这意味着params的长度必须为1。encoding, if supplied, is the encoding to use in the generated XML; the default is UTF-8. encoding(如果提供)是要在生成的XML中使用的编码;默认值为UTF-8。Python’s None value cannot be used in standard XML-RPC; to allow using it via an extension, provide a true value for allow_none.Python的None值不能在标准XML-RPC中使用;要允许通过扩展使用它,请为allow none提供一个true值。

xmlrpc.client.loads(data, use_datetime=False, use_builtin_types=False)

Convert an XML-RPC request or response into Python objects, a (params, methodname). 将XML-RPC请求或响应转换为Python对象,一个(params, methodname)params is a tuple of argument; methodname is a string, or None if no method name is present in the packet. params是一个参数元组;methodname是一个字符串,如果数据包中没有方法名,则为NoneIf the XML-RPC packet represents a fault condition, this function will raise a Fault exception. 如果XML-RPC数据包表示故障情况,则此函数将引发Fault异常。The use_builtin_types flag can be used to cause date/time values to be presented as datetime.datetime objects and binary data to be presented as bytes objects; this flag is false by default.use_builtin_types标志可用于使日期/时间值被呈现为datetime.datetime对象,并且二进制数据被呈现为bytes对象;默认情况下,此标志为false

The obsolete use_datetime flag is similar to use_builtin_types but it applies only to date/time values.过时的use_datetime标志类似于use_builtin_types,但它仅适用于日期/时间值。

Changed in version 3.3:版本3.3中更改: The use_builtin_types flag was added.已添加use_builtin_types标志。

Example of Client Usage客户端使用示例

# simple test program (from the XML-RPC specification)
from xmlrpc.client import ServerProxy, Error
# server = ServerProxy("http://localhost:8000") # local server
with ServerProxy("http://betty.userland.com") as proxy:

print(proxy)

try:
print(proxy.examples.getStateName(41))
except Error as v:
print("ERROR", v)

To access an XML-RPC server through a HTTP proxy, you need to define a custom transport. The following example shows how:要通过HTTP代理访问XML-RPC服务器,需要定义一个自定义传输。以下示例显示了如何:

import http.client
import xmlrpc.client
class ProxiedTransport(xmlrpc.client.Transport):

def set_proxy(self, host, port=None, headers=None):
self.proxy = host, port
self.proxy_headers = headers

def make_connection(self, host):
connection = http.client.HTTPConnection(*self.proxy)
connection.set_tunnel(host, headers=self.proxy_headers)
self._connection = host, connection
return connection

transport = ProxiedTransport()
transport.set_proxy('proxy-server', 8080)
server = xmlrpc.client.ServerProxy('http://betty.userland.com', transport=transport)
print(server.examples.getStateName(41))

Example of Client and Server Usage客户端和服务器使用示例

See SimpleXMLRPCServer Example.请参阅SimpleXMLRPCServer示例

Footnotes

1

This approach has been first presented in a discussion on xmlrpc.com.这种方法首次出现在关于xmlrpccom的讨论中。