Прочитайте объект Zip::Entry после распаковки XML-файла

У меня есть загрузка внешнего XML-файла, который необходимо распаковать и проанализировать. Я скачал и распаковал его, но теперь он застрял как объект Zip::Entry, и я не могу разобрать его с Nokogiri.

require 'open-uri'
require 'zip'
require 'nokogiri'

url = 'https://download.api.bingads.microsoft.com/ReportDownload/Download.aspx?xmlfile'
zip_file = open(url)
# file pulled down successfully => tmp/localpath

unzippedxml = Zip::File.open(zip_file.path) do |z|
  xml_file = z.first
end
#output is my xml file => myxml.xml

unzippedxml.class => Zip::Entry

Nokogiri::XML("unzippedxml")
=> #<Nokogiri::XML::Document:0x212b2c0 name="document")

Как мне разобрать этот файл? Я создал фиктивный XML-файл, который не нужно разархивировать, и я смог разобрать его в консоли, но не могу открыть его.

Любая помощь будет принята с благодарностью!

1 ответ

Решение

Zip::ZipFile представляет весь контейнер Zip; то, что вам нужно вместо этого, находится внутри этого контейнера, объекта класса Zip::ZipEntry, Вы могли бы, например, использовать Zip::ZipFile.read чтобы получить файл с конкретным именем:

require 'zip/zip'

zip = Zip::ZipFile.open('some.zip')                 # open zip
xml_source = zip.read('filename_inside_zip.xml')    # read file contents

# now use the contents of xml_source with Nokogiri

Или, если вы не знаете имя, но в Zip всегда есть только один файл, вы можете просто взять первый:

require 'zip/zip'

zip = Zip::ZipFile.open('some.zip')                 # open zip
entry = zip.entries.reject(&:directory?).first      # take first non-directory
xml_source = entry.get_input_stream{|is| is.read }  # read file contents

# now use the contents of xml_source with Nokogiri
Другие вопросы по тегам