Minule jsme se podívali na formáty txt a csv. Nyní si ukážeme základní zpracování dat ve formátu json a xml.
1 – JSON. Zde si vezmu na výpomoc příklad použitý na www.tutorialspoint.com (https://www.tutorialspoint.com/json/json_ruby_example.htm)
Mějme následující vstupní soubor, který chceme načíst
{ "President": "Alan Isaac", "CEO": "David Richardson", "India": [ "Sachin Tendulkar", "Virender Sehwag", "Gautam Gambhir" ], "Srilanka": [ "Lasith Malinga", "Angelo Mathews", "Kumar Sangakkara" ], "England": [ "Alastair Cook", "Jonathan Trott", "Kevin Pietersen" ] }
V rámci ruby si musíme opět nejdříve vyzádat potřebné knihovny
require 'json'
a pak již můžeme načíst soubor
json = File.read('input.json') obj = JSON.parse(json)
pro parsování stringu do formátu JSON pak použijeme příkaz
JSON.parse(string)
velmi důležitá metoda pak je „generate(obj, pots=nil)“ . Tato umožňuje vytvoření JSON dokumentu z Ruby. Na druhé straně pak máme metodu „load(source, proc = nil, options = {})“, která umožňuje získání ruby datové struktury přímo z JSONu.
nyní se podíváme na jednoduchou ukázku práce s formátem JSON. Jedná se jednoduché cvičení ze script Unicorn College
require "json" data = [1, "hello", true, {3 => 4, "key" => "value"}] serialized_data = JSON.generate(data) puts serialized_data data = JSON.parse(serialized_data) File.open("data.json", "w") do |file| file.write(serialized_data) end pretty_serialiazed_data = JSON.pretty_generate(data) File.open("pretty_data.json", "w") do |file| file.write(pretty_serialiazed_data) end deserialized_data = nil File.open("data.json", "r") do |file| deserialized_data = JSON.parse(file.read) end
2 – XML. Další docela obsáhlou podkapitolou bude práce s xml. Pro zjednodušení a také z praktických důvodů si zde ukážeme pouze zpracování ve spolupráci s knihovnou nokogiri
Opět si musíme nejdříve vyžádat potřičnou knihovnu
require "nokogiri"
Než se ale pustíme dál, tak se podíváme na dvě motody, které následně použijeme. Metoda xpath vrací kolekci, kdežto metoda at_xpath nám vrátí první položku takovéto kolekce.
Nyní již pojďme na vlastní načítání, zde využiji opět ukázku ze skript Unicorn College
Mějme xml dokument s následující strukturou
James Smith
ten pak následně načítáme tímto způsobem
students = [] File.open("study_results.xml", "r") do |file| doc = Nokogiri::XML::Document.parse(file) doc.root.xpath("student").each do |student_element| first_name = student_element.at_xpath("first_name").content last_name = student_element.at_xpath("last_name").content date_of_birth_element = student_element.at_xpath("date_of_birth") day = date_of_birth_element["day"].to_i month = date_of_birth_element["month"].to_i year = date_of_birth_element["year"].to_i student = Student.new(first_name, last_name, Time.new(year, month, day)) study_results = {} student_element.at_xpath("study_results").xpath("subject").each do |subject_element| subject_code = subject_element["code"] grade = subject_element["grade"] study_results[subject_code] = grade end student.study_results = study_results students << student end end
Jak je vidět i samotný code odráží komplexnost dokumentu. Nejinak je tomu u zápisu, kde se opět podíváme na scripta z Unicorn College, která nám přiblíží zápis s pomocí třídy Nokogiri::XML:Builder.
require "nokogiri" require "yaml" require_relative "quiz_classes.rb" source_file = "quiz_object.yaml" target_file = "quiz.xml" # load quiz data quiz = YAML.load_file(source_file) # create a new Builder instance builder = Nokogiri::XML::Builder.new do |xml| # create the root element ("quiz") xml.quiz({"name" => quiz.name, "author" => quiz.author}) do # iterate over all questions quiz.questions.each do |question| # create a "question" element xml.question({"text" => question.text}) do # iterate over all answers question.answers.each do |answer| # create an "answer" element xml.answer(answer.text, {"correct" => answer.correct ? 1 : 0}) end end end end end # save the XML document to a file File.open(target_file, "w") do |file| file.puts builder.to_xml end
Výsledný výstup pak vypadá následovně
Torino San Marino Vatikan Terst