Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
<section name="Space"> <book isbn="0684835509"> <title>The Case for Mars</title> <author>Robert Zubrin</author> <description>Pushing toward a second home for the human race. </description> </book> <book isbn="074325631X"> <title>First Man: The Life of Neil A. Armstrong</title> <author>James R. Hansen</author> <description>Definitive biography of the first man on the moon. </description> </book> </section></library>15.1.1. Древовидное представление
Сначала покажем, как работать с ХМL-документом, представленным в виде дерева. Для начала затребуем библиотеку
rexml/documentinclude rexmlrequire 'rexml/document'include REXMLinput = File.new("books.xml")doc = Document.new(input)root = doc.rootputs root.attributes["shelf"] # Недавние приобретенияdoc.elements.each("library/section") { |e| puts e.attributes["name"] }# Выводится:# Ruby# Spacedoc.elements.each("*/section/book") { |e| puts e.attributes["isbn"] }# Выводится:# 0672328844# 0321445619# 0684835509# 074325631Xsec2 = root.elements[2]author = sec2.elements[1].elements["author"].text # Robert ZubrinОбратите внимание: атрибуты представляются в виде хэша. Обращаться к элементам можно либо по пути, либо по номеру. В последнем случае учтите, что согласно спецификации XML индексация элементов начинается с 1, а не с 0, как в Ruby.
15.1.2. Потоковый разбор
А теперь попробуем разобрать тот же самый файл в потоковом стиле (на практике это вряд ли понадобилось бы, потому что размер файла невелик). У этого подхода несколько вариантов, в листинге 15.3 показан один из них. Идея в том, чтобы определить класс слушателя, методы которого анализатор будет вызывать для обработки событий.
require 'rexml/document'require 'rexml/streamlistener'include REXMLclass MyListener include REXML::StreamListener def tag_start(*args) puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}" end def text(data) return if data =~ /^w*$/ # Ничего, кроме пропусков. abbrev = data[0..40] + (data.length > 40 ? "..." : "") puts " text : #{abbrev.inspect}" endendlist = MyListener.newsource = File.new "books.xml"Document.parse_stream(source, list)В этом нам поможет класс
StreamListenertag_openmethod_missingtextПрограмма в листинге 15.3 протоколирует обнаружение каждого открывающего и каждого закрывающего тега. Результат работы показан в листинге 15.4 (для краткости текст приведен не полностью).
tag_start: "library", {"shelf"=>"Recent Acquisitions"}tag_start: "section", {"name"=>"Ruby"}tag_start: "book", {"isbn"=>"0672328844"}tag_start: "title", {} text : "The Ruby Way"tag_start: "author", {} text : "Hal Fulton"tag_start: "description", {} text : "Second edition. The book you are now read..."tag_start: "section", {"name"=>"Space"}
