如何在Ruby中解析XML-RPC格式的XML?
我需要在Ruby中解析一些XML-RPC格式的XML。我没有访问XML-RPC服务的权限,我只想将从此类服务返回的XML字符串转换为相应的Ruby对象(散列,数组,字符串等)。如何在Ruby中解析XML-RPC格式的XML?
我周围玩内置XML-RPC的东西(用Ruby 1.9.3),但我不走得很远:
require 'xmlrpc/parser'
parser = XMLRPC::XMLParser::XMLParser.new
导致此异常:
LoadError: cannot load such file -- xmltreebuilder
from /Users/johannes/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/johannes/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/johannes/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/xmlrpc/parser.rb:620:in `initialize'
from (irb):2:in `new'
from (irb):2
from /Users/johannes/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
然后我试图实例化不同的XMLParser子类,都无济于事。
你有什么关于如何让这个工作的指针?是否有可能在不使用带有内置库的XMLRPC :: Client的情况下解析RPC XML?
谢谢!
更新:
这工作,但它是哦,所以,非常难看。这不可能是正确的:
require 'xmlrpc/client'
require "rexml/document"
xml = %{<answer>
<value>
<struct>
<member><name>test</name><value><string>hello</string></value></member>
<member><name>age</name><value><i4>12</i4></value></member>
<member>
<name>requirements</name>
<value>
<struct>
<member>
<name>confirmation</name>
<value>
<array>
<data>
<value><string>Bread</string></value>
<value><string>Butter</string></value>
</data>
</array>
</value>
</member>
<member>
<name>document</name>
<value>
<array>
<data>
<value><string>Tic</string></value>
<value><string>Tac</string></value>
<value><string>Toe</string></value>
</data>
</array>
</value>
</member>
</struct>
</value>
</member>
<member><name>width</name><value><i4>10</i4></value></member>
<member><name>height</name><value><i4>2</i4></value></member>
</struct>
</value>
</answer>}
parser = XMLRPC::XMLParser::REXMLStreamParser::StreamListener.new
parser.parse(xml)
puts "Value (accessor): '#{parser.value}'"
puts "Values (accessor): '#{parser.values}'"
puts "Value (instance_variable_get): '#{parser.instance_variable_get('@value')}'"
必须有更好的方法!
这是输出:
Value (accessor): ''
Values (accessor): ''
Value (instance_variable_get): '{"test"=>"hello", "age"=>12, "requirements"=>{"confirmation"=>["Bread", "Butter"], "document"=>["Tic", "Tac", "Toe"]}, "width"=>10, "height"=>2}'
这使得我的眼睛受伤了。
这是最接近的一个解决方案,我能找到的:
这工作,但它是哦,所以,非常难看。这不可能是正确的:
require 'xmlrpc/client'
require "rexml/document"
xml = %{<answer>
<value>
<struct>
<member><name>test</name><value><string>hello</string></value></member>
<member><name>age</name><value><i4>12</i4></value></member>
<member>
<name>requirements</name>
<value>
<struct>
<member>
<name>confirmation</name>
<value>
<array>
<data>
<value><string>Bread</string></value>
<value><string>Butter</string></value>
</data>
</array>
</value>
</member>
<member>
<name>document</name>
<value>
<array>
<data>
<value><string>Tic</string></value>
<value><string>Tac</string></value>
<value><string>Toe</string></value>
</data>
</array>
</value>
</member>
</struct>
</value>
</member>
<member><name>width</name><value><i4>10</i4></value></member>
<member><name>height</name><value><i4>2</i4></value></member>
</struct>
</value>
</answer>}
parser = XMLRPC::XMLParser::REXMLStreamParser::StreamListener.new
parser.parse(xml)
puts "Value (accessor): '#{parser.value}'"
puts "Values (accessor): '#{parser.values}'"
puts "Value (instance_variable_get): '#{parser.instance_variable_get('@value')}'"
必须有更好的方法!
这是输出:
Value (accessor): ''
Values (accessor): ''
Value (instance_variable_get): '{"test"=>"hello", "age"=>12, "requirements"=>{"confirmation"=>["Bread", "Butter"], "document"=>["Tic", "Tac", "Toe"]}, "width"=>10, "height"=>2}'
这使得我的眼睛受伤了。
的XMLRPC库明显带有多个解析器和默认是XMLTreeParser
这就要求图书馆xmltreebuilder(我不知道和这显然不是标准库的一部分)。 但也许你可以尝试另一个解析器?使用XMLRPC::XMLParser.each_installed_parser {|p| puts p.class}
,您将获得所有(可实例化)解析器的列表。所以,你可能会得到别人的一个正常工作......
检查 '引入nokogiri' 宝石:
irb> require 'nokogiri'
irb> doc = Nokogiri::XML('<root><a>test</a></root>')
irb> puts (doc/'root/a').first.text # => 'test'
或
irb> puts doc.xpath('doc/root/a').first.text
等
谢谢,我已经广泛地使用Nokogiri,并且我用Nokogiri编写了自己的XML-RPC解析器。不过,我不想重新发明轮子。这就是为什么我想了解如何使用现有的解决方案来解析XML-RPC。 –
与@mfojtik我打算推荐Nokogiri,因为它是一款出色的XML解析器,但我通过Google搜索几乎找到了Rapuncel。它是一个基于Nokogiri的XML-RPC客户端,专门用于发送/接收XML-RPC并解析它。
不知道它是否被维护了,但它可能值得一试。如果没有,你可以使用Nokogiri作为基础,因为它看起来不太复杂。
谢谢,我试过了。唯一不引发异常的是'REXMLStreamParser',即使那个不能按预期工作(请参阅更新后的问题)。 –