2

(gzipではなく)zip形式で圧縮されたXMLで応答するWebサービスを使用しています。Rubyが応答をgzip形式で自動的に解凍することは知っていますが、使用しているサービスにはgzip形式がありません。

サービスの応答を取得するために使用しているコードは次のとおりです。

require 'net/http'
require 'uri'
require 'nokogiri'

xml = Nokogiri::XML::Builder.new do |xml|
    xml.method {
        xml.param1 'value1'
        xml.param2 'value2'
    }
end

url = URI.parse('http://url.to.webservice/')
request = Net::HTTP::Post.new(url.path)
request.content_type = 'text/xml'
request.body = xml.to_xml

response = Net::HTTP.new(url.host, url.port).start { |http| http.request(request) }

case response
when Net::HTTPSuccess, Net::HTTPRedirection
    # Decompress Zip response
else
    puts "Request error."
end

Rubyを使用してZip応答を解凍する組み込みのメソッドはありますか?ありがとう!

4

2 に答える 2

3

このソリューションは、一時ファイルを使用するため、非常に醜いです。しかし、ルビーで .zip ファイルを処理するためのより良い方法を見つけることができませんでした:-\ 必ず ruby​​zip gem をインストールしてからgem install rubyzip、それを次のように要求してください。require 'zip/zip'

  t=Tempfile.new('1.xml.zip')
  File.open(t.path, 'w') do |f|
    f.write response.body
  end

  Zip::ZipFile.open(t.path) do |files|
    files.each do |file|
      puts Nokogiri::XML.parse(file.get_input_stream)
    end
  end
  t.delete

コメントの代わりにこのコードを入れてください;)

于 2012-11-19T16:54:55.750 に答える
1

zipruby次のように、を使用してオンザフライでファイルを解凍できるはずです。

require 'zipruby'

Zip::Archive.open_buffer(response.body) do |ar|
   ar.each do |zf|
      if zf.directory?
         FileUtils.mkdir_p(zf.name)
      else
         dirname = File.dirname(zf.name)
         FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
         open(zf.name, 'wb') do |f|
            f << zf.read
         end
      end
   end
end

これは、Web サービスが送信する zip ファイルに複数のファイルが含まれている可能性があることを考慮に入れています。サービスが単一のファイルのみを送信している場合は、次のようなより単純なソリューションを使用できます。

Zip::Archive.open_buffer(response.body) do |ar|
   ar.fopen(0) do |zf|
      open(zf.name, 'wb') do |f|
         f << zf.read
      end
   end
end
于 2012-11-19T20:48:29.877 に答える