English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Учебник по Ruby для начинающих

Учебник по Ruby для продвинутых пользователей

Учебник Ruby XML, XSLT и XPath

Что такое XML?

XML - это расширяемый язык маркировки (eXtensible Markup Language).

XML - это расширяемый язык маркировки, подмножество общего языка маркировки, это язык маркировки, который используется для маркировки электронных документов, чтобы сделать их структурированными.

Это может быть использовано для маркировки данных, определения типов данных и является языком исходного кода, который позволяет пользователям определять свои языки маркеров. Он非常适合 для веб-трансляций, предоставляя единый метод для описания и обмена структурированными данными, независимыми от приложений или поставщиков.

Более подробную информацию можно найти в нашем Учебник XML

Структура парсера XML и API

Основные парсеры XML - это DOM и SAX.

  • Парсер SAX основан на обработке событий и требует сканирования документа от начала до конца. В процессе сканирования, при встрече каждой грамматической структуры, вызывается обработчик событий для этой конкретной грамматической структуры, и отправляется событие приложению.

  • DOM - это модель объектов документов, которая строит иерархическую грамматическую структуру документа, создает дерево DOM в памяти, а узлы DOM представляются в виде объектов. После парсинга документа,整个 DOM-дерево документа будет放在 памяти.

Парсинг и создание XML в Ruby

Парсер REXML может быть использован для парсинга документов XML в Ruby.

Библиотека REXML - это XML-инструментальный набор для Ruby, написанный на чистом Ruby и соблюдающий спецификацию XML 1.0.

В Ruby 1.8 и более поздних версиях REXML будет включен в стандартную библиотеку Ruby.

Путь к библиотеке REXML: rexml/document

Все методы и классы заключены в модуль REXML.

Преимущества парсера REXML по сравнению с другими парсерами:

  • На 100% написана на Ruby.

  • Подходит для парсеров SAX и DOM.

  • Это легковесная версия, менее 2000 строк кода.

  • Легко понимаемые методы и классы.

  • Основана на API SAX2 и поддержке XPath в полном объем.

  • Установите Ruby, не требуя отдельной установки.

Ниже приведён пример XML кода, сохраните его как movies.xml:

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
   <type>Война, Триллер</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Говорить о войне США и Японии</description>
</movie>
<movie title="Transformers">
   <type>Аниме, Научная фантастика</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>Научная фантастика</description>
</movie>
   <movie title="Trigun">
   <type>Аниме, Акция</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Ваш стамест!</description>
</movie>
<movie title="Ishtar">
   <type>Комедия</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Видимое скудоумие</description>
</movie>
</collection>

DOM парсер

Давайте сначала разберём XML данные, сначала мы вводим библиотеку rexml/document, обычно мы можем ввести REXML в верхнем уровне пространства имён:

Онлайн-пример

#!/usr/bin/ruby -w
 

require 'rexml/document'
 
include REXML
xmlfile = File.new("movies.xml")
 
# Получение корневого элемента
root = xmldoc.root
puts "Корневой элемент: " + root.attributes["shelf"]
 
# Вывод заголовка фильма
xmldoc.elements.each("collection/movie") { 
   puts "Название фильма: " + e.attributes["title"] 
}
 
# Выведение всех типов фильмов
xmldoc.elements.each("collection/movie/type") {
   |e| puts "Тип фильма: " + e.text 
}
 
# Выведение всех описаний фильмов
xmldoc.elements.each("collection/movie/description") {
   |e| puts "Описание фильма: " + e.text 
}

Результат выполнения примера выше будет следующим:

Корневой элемент: Новые поступления
Название фильма: Враг за спиной
Название фильма: Transformers
Название фильма: Trigun
Название фильма: Ishtar
Тип фильма: Война, Триллер
Тип фильма: Аниме, Научная фантастика
Тип фильма: Аниме, Действие
Тип фильма: Комедия
Описание фильма: Рассказ о войне между США и Японией
Описание фильма: Научная фантастика
Описание фильма: Vash the Stampede!
Описание фильма: Видимое скудоумие
СAX-подобный анализ:

СAX парсер

Обработка одного и того же файла данных: movies.xml, не рекомендуется использовать SAX для обработки файла небольшого размера, вот пример:

Онлайн-пример

#!/usr/bin/ruby -w
 

require 'rexml/streamlistener'
require 'rexml/document'
 
 
class 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}"
  end
end
 
list = MyListener.new
include REXML
Document.parse_stream(xmlfile, list)

Результат вывода:

tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
  text   :   "War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Talk about a US-Japan war"
tag_start: "movie", {"title"=>"Transformers"}
tag_start: "type", {}
  text   :   "Anime, Science Fiction"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "A scientific fiction"
tag_start: "movie", {"title"=>"Trigun"}
tag_start: "type", {}
  text   :   "Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Vash the Stampede!"
tag_start: "movie", {"title"=>"Ishtar"}
tag_start: "type", {}
tag_start: "format", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Viewable boredom"

XPath и Ruby

Мы можем использовать XPath для просмотра XML, XPath - это язык для поиска информации в документе XML (смотрите также:)Уроки XPath)。

XPath - это язык XML-пути, который является языком для определения местоположения某一个 части документа XML (подмножество общего языка разметки). XPath основан на иерархической структуре XML, предоставляя возможность поиска узлов в структуре данных дерева.

Ruby поддерживает XPath через класс REXML, который основан на анализе дерева (модель объекта документа).

Онлайн-пример

#!/usr/bin/ruby -w
 

require 'rexml/document'
 
include REXML
xmlfile = File.new("movies.xml")
 
xmldoc = Document.new(xmlfile)
# Информация о первом фильме
movie = XPath.first(xmldoc, "//movie")
 
# p movie
# Вывести все типы фильмов
 
# Получить все типы форматов фильмов, вернув массив
names = XPath.match(xmldoc, "//format").map {|x| x.text}
p names

Результат выполнения примера выше будет следующим:

<movie title='Враг за спиной'>...</movie>
Война, Триллер
Аниме, Научная фантастика
Аниме, Действие
Комедия
["DVD", "DVD", "DVD", "VHS"]

XSLT и Ruby

В Ruby есть два парсера XSLT, следующий является кратким описанием:

Ruby-Sablotron

Этот парсер был написан и поддерживается Масаюки Такахаши. Он написан в основном для операционной системы Linux и требует следующих библиотек:

  • Sablot

  • Iconv

  • Expat

Вы можете найти их в Ruby-Sablotron Найдите эти библиотеки.

XSLT4R

XSLT4R был написан Михаилом Нойманном. XSLT4R используется для простого командного интерфейса и может быть использован третьими сторонними приложениями для преобразования XML-документов.

XSLT4R требует операции XMLScan, которая включает архив XSLT4R, являющийся 100% модулями Ruby. Эти модули можно установить стандартными методами установки Ruby (т.е. Ruby install.rb).

Синтаксис XSLT4R следующий:

ruby xslt.rb stylesheet.xsl document.xml [аргументы]

Если вы хотите использовать XSLT4R в приложении, вы можете включить XSLT и ввести необходимые вам параметры. Пример показан ниже:

Онлайн-пример

require "xslt"
 
stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }
 
sheet = XSLT::Stylesheet.new( stylesheet, arguments )
 
# output to StdOut
sheet.apply( xml_doc )
 
# output to 'str'
str = ""
sheet.output = [ str ]
sheet.apply( xml_doc )

Более подробная информация