与普通 XML 相比,XML-RPC 有啥好处?

Posted

技术标签:

【中文标题】与普通 XML 相比,XML-RPC 有啥好处?【英文标题】:What is the benefit of XML-RPC over plain XML?与普通 XML 相比,XML-RPC 有什么好处? 【发布时间】:2010-11-25 11:45:17 【问题描述】:

我的公司已经使用XML-RPC 有一段时间了,但最近我想知道 XML-RPC 与纯 XML 相比有什么好处。首先,这是可怕的“肥胖”,请考虑:

<struct>
    <member>
        <name>ROOM_ID</name>
        <value>
            <int>1</int>
        </value>
    </member>

    <member>
        <name>CODE</name>
        <value>
            <string>MR-101</string>
        </value>
    </member>

    <member>
        <name>NAME</name>
        <value>
            <string>Math Room</string>
        </value>
    </member>

    <member>
        <name>CAPACITY</name>
        <value>
            <int>30</int>
        </value>
    </member>
</struct>

与此相比:

<room><ROOM_ID>1</ROOM_ID><CODE>MR-101</CODE>
<NAME>Math Room</NAME><CAPACITY>30</CAPACITY></room>

甚至这个:

<room ROOM_ID=1 CODE=MR-101 NAME=”Math Room” CAPACITY=30 />

其次,XML-RPC 似乎相当普遍,但不是很普遍,而且我对 C++ 和 php 对它的支持印象不深。我在两种语言中尝试过的所有库都遇到了问题。

第三,在我看来,我可以像使用 XML-RPC 一样轻松地使用纯 XML 进行远程过程调用。 (9/9/2009):每种语言都有用于将语言级对象序列化为 XML 的库。 XML 和 XML-RPC 都需要定义应用程序级别的模式,例如,字段应该如何拼写,但都不需要定义任何额外的模式。许多人使用纯 XML 进行 RPC 调用。

那么 XML-RPC 的附加值是什么?

【问题讨论】:

【参考方案1】:

简单: XML RPC 提供

传递方法名称的标准方式 打字系统。我经常使用电话号码,它们是字符串,而不是数字。 返回错误的标准方法 内省(几乎)免费

所有这些都基于标准 XML。

【讨论】:

【参考方案2】:

简短的回答是:这两种协议都可用于进行远程过程调用 (RPC)。两种协议都需要定义应用程序级别的模式,一般来说,两种协议都不需要任何额外的模式来定义如何序列化语言级别的对象(请参阅下面的一些详细信息)。

但是,XmlRpc 得到了库的更大支持,这些库使用语言的元编程(反射)特性将 XmlRpc 调用直接(嗯,绝不是 100% 直接)映射到语言级别的函数调用。对 XmlRpc 的支持比纯 XML 更好的原因是 (a) XmlRpc 支持者的市场营销的历史意外/结果,或者 (b) 下面列出的小翻译问题的总和使天平倾向于支持XmlRpc。

另一方面,XmlRpc 有两个主要缺点:(1) 它需要大约 4 倍的带宽,以及 (2) 它颠覆了 XML 模式验证工具的意图:每个数据包都将简单地标记为“是的,这是有效的 XmlRpc”,无论应用程序级字段中的拼写错误和遗漏如何。

长答案:

与流行的看法相反,您不需要一个标准来定义如何在纯 XML 中编码语言级对象 - 通常只有一种“合理”的方式(假设应用程序级架构定义了您是否使用 XML 属性),例如:

class Room 
    int id=1;
    String code="MR-101";
    String name="Maths room";
    int capacity=30;
;

编码为:

<Room>
    <id>1</id>
    <code>MR-101</code>
    <name>Maths room</name>
    <capacity>30</capacity>
</Room>

XmlRpc 专门设计用于促进在 RPC 调用中自动序列化/反序列化语言级对象的库的创建,因此以这种方式使用它具有一些小优势:

    对于纯 XML,具有单个成员的结构可能会与具有单个元素的数组相混淆。

    XmlRpc 定义标准时间/日期格式。 虽然时区和纯时间或纯日期时间戳的处理是在应用程序级别定义的。

    XmlRpc 允许您将参数传递给函数而不用命名它们;纯 XML RPC 调用要求您命名每个参数。

    XmlRpc 定义了一种标准方法来命名被调用的方法:“methodName”。使用纯 XML,根节点的标记通常用于此目的,但也可以使用其他方法。

    XmlRpc 定义了一个简单的类型系统:整数、字符串等。 请注意,对于静态类型语言,无论如何都必须将类型编译到目标对象中,因此是已知的,对于动态类型语言,通常 int 和 float 以及字符串可以互换使用;另请注意,XmlRpc 类型系统通常与可能具有多种整数类型的目标语言的类型系统匹配不佳,依此类推。

    XmlRpc 库通常直接与 Http 库集成,而 Xml 序列化库 all(?) 要求应用程序程序员将 XML 文本传递给 Http 调用。在 Java/Python/C# 等更现代的语言中,这是一件小事,但对于例如 Java/Python/C# 而言并非如此。 C++。

    有一种“营销观念”,即 XML 描述“文档”,而 XmlRpc 是为过程调用而设计的。这种感觉是发送 XmlRpc 消息包含服务器执行某些操作的义务,而这种感觉对于纯 XML 并不那么强烈。

有些人会说“谁在乎 - 使用递归下降/DOM/SAX 解析 XML 数据还是很容易的”,在这种情况下,上述大多数反对意见都是无关紧要的。

对于那些仍然喜欢自动创建本地语言对象的易用性的人来说,许多主要语言都有库,这些库可以自动将语言级对象序列化为 XML,而无需借助 XmlRpc,例如:

.NET - Java - Python

XmlRpc 的成功可能源于自动创建语言级别对象的库的可用性,而这些库又由于以下列表而优于它们的普通 XML 对应物以上问题。

XmlRpc的缺点是:

正如问题中提到的,它非常肥胖

对纯 XML 的支持无处不在,通常不需要与大型第 3 方库集成。无论如何,许多应用程序都需要将自动创建的对象转换为应用程序自己的对象。

许多 XmlRpc 实现无法生成程序员期望的真正语言级对象,而是需要例如字段或额外语法的运行时查找。

如果使用架构定义文档(例如 DTD 文件)来验证 RPC 调用,那么您将无法检查应用程序级架构 - DTD 文件只会告诉您“这是有效的XmlRpc”。据我所知,没有任何标准方法可以使用基于 XmlRpc 的协议来定义应用程序级架构。

【讨论】:

【参考方案3】:

XmlRpc 的主要价值在于您不必编写代码来生成和解析通过 HTTP 传递的 XML 文档,因为 XML-RPC 是用于表示函数调用的预定义 XML Schema。

即使库不是最佳的,也有一个额外的派生值,因为使用这种类型的系统允许您将远程接口定义为基本语言接口(C++ 抽象类、Java 接口等),它们独立于用于在组件之间进行通信的有线协议。

将接口定义与有线协议(XML-RPC、SOAP 等)分开允许您最终在适当的情况下替换为替代协议。例如,在我们的系统中,我们的 Flex 前端使用 Hessian 公开服务,我们的 .NET 前端使用 SOAP(Hessian .Net 库具有不允许的许可证)。

通过现在坚持使用 XML-RPC,您可以选择在未来切换到其他一些协议,而只需进行最少的重构。

【讨论】:

使用纯 XML,无需编写代码来生成和解析 XML 文档。我很容易找到已经为 C# 和 PHP 执行此操作的库的链接,其方式与库为 XmlRpc 执行此操作的方式完全相同。如果我有执行 XML 的代码,那么我不会对多线协议 API 感兴趣。【参考方案4】:

主要优点是有人已经为您制定了调用模式。这在具有反射的语言中特别有用,在这种语言中,您可以盲目地将复杂的结构传递给 RPC 调用,它会为您解决如何将其转换为 XML 的问题。它在 C++ 中的价值较低,您必须明确告诉 XML-RPC 库所有数据类型是什么。

你说得对,它并没有席卷世界。您在图书馆中发现的奇怪之处在于这种低水平的兴趣。我自己用过两个,都发现了两个错误。两者都是废弃软件,所以我无法将补丁发回,所以我有两者的私有补丁版本。叹息。

【讨论】:

Warren,如果可以使用反射将数据结构序列化为 XmlRpc,是否也可以使用反射将数据结构序列化为纯 XML? 当然可以,但是您必须自己编写所有序列化代码,现在您已经发明了另一种专有的 XML 模式。为了简单性和兼容性,有话要说。 “另一种专有模式” - 这意味着将对象编码为 XML 的方法不止一种。在上面的例子中,如果我们简单地禁止属性,那么肯定只有一种方法来编码对象吗?它不再发明任何“专有模式”。事实上,已经有一些库可以将对象序列化为用于 C# 和 PHP 的纯 XML,并且可能适用于大多数语言。 有无数种不兼容的方法可以将任何给定的数据编码为 XML。您可以争辩说,一种用途更好,另一种用途的编码更好,但是如果每种用途都有不同的编码,则没有兼容性,也没有重用代码。我并不是要告诉您必须使用 XML-RPC。我只是建议您不要仅仅因为您更喜欢您的特定车轮而拒绝它。考虑那些必须编写读取这些相同数据结构的程序的人的需求。 “无限不兼容的编码方式”?如果我们应用“不允许属性”规则,您能否建议一种将上述对象编码为纯 XML 的替代方法? XmlRpc 并没有消除定义应用程序级别架构的需要,例如如何拼写字段名称。每种语言都有一个将对象序列化为纯 XML 的库,它们似乎不认为如何对对象进行编码。【参考方案5】:

让我从头开始,倒退:

3) 是的,您可以使用纯 XML(或纯字符串或二进制协议)进行远程过程调用。不同之处在于,XmlRpc 是一个定义明确的协议,具有许多可用的实现,这意味着 a) 您不必编写尽可能多的代码 b) 您可以与网络另一端的任何人进行互操作,而无需您或他们必须处理彼此的代码。 XmlRpc 充当桥梁。

2) 我会说它是quite ubiquitous :-) 我在 Java 中使用过 XmlRpc,因此无法评论 C++/PHP 实现问题。

1) 是由于上面的 (3)。协议的冗长既是其互操作性的结果,也是其原因。

【讨论】:

3) 如果我要使用纯字符串或二进制进行远程过程调用,这将是可怕的,并且需要为每个交互设计格式。但是纯 XML 为传递结构化值提供了一种定义明确的格式。我认为您没有回答“XmlRpc 对 XML 有什么影响?”这个问题。 1) 我的示例将 XmlRpc 与 XML 进行了比较,并证明您无需冗长即可互操作。 XML 被认为是一种有利于互操作性的协议。 你错了。以你的例子,&lt;room ROOM_ID=1 CODE=MR-101 NAME=”Math Room” CAPACITY=30 /&gt; 如果我要通过电线接收它,我怎么知道如何将它解组为一个对象?这与获取 room|1|MR-101|Math Room|30 并依赖现场顺序没有什么不同。关键是,XML-RPC 提供了一个定义良好的通信协议 - XML 本身没有。 我不明白依赖字段顺序的意义。在这种情况下,属性(或标签)具有名称。为什么不看字段名而不看字段顺序? 您的 XML one-liner 和我的管道分隔字符串都可以成功地用于两方之间的通信。在这两种情况下,接收方都必须已经知道对象结构(例如,您的 XML 缺少数据类型,更不用说除了当前形式的简单结构之外无法传达任何内容);如果我确实知道我在解组什么,我真的不需要字段名称。关键是 - 您的 XML 示例不适合现实生活中的通信,而 XML-RPC 是。 XML 能够表示任意复杂的树 - 我没有理解您关于“除了简单的结构之外无法传达任何东西”的观点。数据类型似乎是 XmlRpc 添加的唯一内容......(尽管不同语言之间的类型系统之间经常存在不匹配。)在任何基于 XmlRpc 的协议中,都需要对对象结构有一些共同的理解,例如期望什么字段名称,但 XML 和 XmlRpc 都允许您添加字段和重新排序字段而不影响语义。 XML 必须足以用于现实生活中的通信,因为它的使用非常广泛。

以上是关于与普通 XML 相比,XML-RPC 有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 与原生 MongoDB 相比有啥好处?

与 makeStyles 相比,使用 withStyles 有啥好处?

拥有多个线程池与单个线程池相比有啥好处?

与 std::inserter 相比,std::back_inserter 有啥好处?

与简单地创建派生类指针相比,将基类绑定到派生类有啥好处?

在 redux 中使用 thunk 中间件与使用常规函数作为异步操作创建者相比有啥好处? [关闭]