2

我正在使用以 zip 格式(不是 gzip)压缩的 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

这个解决方案非常难看,因为它使用临时文件。但是我找不到更好的方法来处理 ruby​​ 中的 .zip 文件:-\ 确保安装 ruby​​zip gem w/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 回答