1

RubyでXML-RPC形式のXMLを解析する必要があります。XML-RPCサービスにアクセスできません。そのようなサービスから返されるXML文字列をそれぞれのRubyオブジェクト(ハッシュ、配列、文​​字列など)に変換したいだけです。

組み込みのXMLRPC(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}'

これは私の目を傷つけます。

4

5 に答える 5

1

'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

于 2012-10-24T14:53:56.097 に答える
1

この質問は古くなっている可能性がありますが、「rubyparsexmlrpc」をグーグルで検索した場合でもトップヒットです。

ルビーXMLRPC文字列は、次を使用してより簡単に解析できます。XMLRPC::Marshal

require 'xmlrpc/marshal'

def parse_xml_rpc(xml_string)
  parser = XMLRPC::Marshal.new
  parser.load_call(xml_string)
end

上記の関数は、最初に関数の名前を含み、次に渡された引数の配列を含むタプルを返します。

str = "<?xml version=\"1.0\" ?><methodCall><methodName>function_name</methodName><params><param><value><string>arg1</string></value></param><param><value><boolean>1</boolean></value></param><param><value><double>27.5</double></value></param></params></methodCall>\n"

parse_xml_rpc(str)
=> ["function_name", ["arg1", true, 27.5]]
于 2019-08-07T13:10:14.243 に答える
0

xmlrpcライブラリには明らかに複数のパーサーが付属しており、デフォルトでXMLTreeParserはライブラリxmltreebuilderが必要です(これは私にはわかりませんが、明らかに標準ライブラリの一部ではありません)。しかし、多分あなたは別のパーサーを試すことができますか?を使用しXMLRPC::XMLParser.each_installed_parser {|p| puts p.class}て、すべての(インスタンス化可能な)パーサーのリストを取得します。したがって、他の1つを適切に動作させることができます...

于 2012-10-22T14:30:02.280 に答える
0

@mfojtikと同様に、優れたXMLパーサーであるNokogiriを提案するつもりでしたが、グーグルでRapuncelに出くわしました。これは、XML-RPCの送受信と解析のために特別に構築されたNokogiriベースのXML-RPCクライアントです。

それがもう維持されているかどうかはわかりませんが、試してみる価値があるかもしれません。そうでなければ、それほど複雑に見えないので、いつでもノコギリをベースとして自分で書くことができます。

于 2012-10-25T00:39:57.380 に答える
0

これは私が見つけることができる解決策に最も近いものです:

これは機能しますが、非常に醜いです。これは正しくありえません:

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

これは私の目を傷つけます。

于 2012-10-29T09:11:02.400 に答える