Учебники

Ruby — учебник по XML, XSLT и XPath

Расширяемый язык разметки (XML) — это язык разметки, очень похожий на HTML или SGML. Это рекомендуется Консорциумом World Wide Web и доступно в качестве открытого стандарта.

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

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

XML Parser Архитектуры и API

Для синтаксических анализаторов XML доступны два варианта:

  • SAX-like (потоковые интерфейсы) — здесь вы регистрируете обратные вызовы для интересующих событий, а затем позволяете анализатору проходить через документ. Это полезно, когда ваши документы большие или у вас есть ограничения памяти, он анализирует файл, когда читает его с диска, и весь файл никогда не сохраняется в памяти.

  • DOM-like (интерфейсы дерева объектов) — это рекомендация Консорциума World Wide Web, в которой весь файл считывается в память и хранится в иерархической (основанной на дереве) форме для представления всех возможностей документа XML.

SAX-like (потоковые интерфейсы) — здесь вы регистрируете обратные вызовы для интересующих событий, а затем позволяете анализатору проходить через документ. Это полезно, когда ваши документы большие или у вас есть ограничения памяти, он анализирует файл, когда читает его с диска, и весь файл никогда не сохраняется в памяти.

DOM-like (интерфейсы дерева объектов) — это рекомендация Консорциума World Wide Web, в которой весь файл считывается в память и хранится в иерархической (основанной на дереве) форме для представления всех возможностей документа XML.

Очевидно, что SAX не может обрабатывать информацию так же быстро, как DOM при работе с большими файлами. С другой стороны, использование исключительно DOM действительно может убить ваши ресурсы, особенно если они используются для большого количества маленьких файлов.

SAX доступен только для чтения, а DOM позволяет вносить изменения в файл XML. Поскольку эти два разных API буквально дополняют друг друга, нет никаких причин, по которым вы не можете использовать их оба для больших проектов.

Разбор и создание XML с использованием Ruby

Наиболее распространенный способ манипулировать XML — это библиотека REXML Шона Рассела. С 2002 года REXML является частью стандартного дистрибутива Ruby.

REXML — это чистый XML-процессор Ruby, соответствующий стандарту XML 1.0. Это не проверяющий процессор, который проходит все не подтверждающие проверки соответствия OASIS.

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

  • На Ruby написано 100 процентов.
  • Может использоваться как для SAX, так и для DOM-анализа.
  • Это легкий, менее 2000 строк кода.
  • Методы и классы действительно просты для понимания.
  • API на основе SAX2 и полная поддержка XPath.
  • Поставляется с установкой Ruby и не требует отдельной установки.

Для всех наших примеров XML-кода давайте использовать простой XML-файл в качестве входных данных —

<collection shelf = "New Arrivals">
   <movie title = "Enemy Behind">
      <type>War, Thriller</type>
      <format>DVD</format>
      <year>2003</year>
      <rating>PG</rating>
      <stars>10</stars>
      <description>Talk about a US-Japan war</description>
   </movie>
   <movie title = "Transformers">
      <type>Anime, Science Fiction</type>
      <format>DVD</format>
      <year>1989</year>
      <rating>R</rating>
      <stars>8</stars>
      <description>A schientific fiction</description>
   </movie>
   <movie title = "Trigun">
      <type>Anime, Action</type>
      <format>DVD</format>
      <episodes>4</episodes>
      <rating>PG</rating>
      <stars>10</stars>
      <description>Vash the Stampede!</description>
   </movie>
   <movie title = "Ishtar">
      <type>Comedy</type>
      <format>VHS</format>
      <rating>PG</rating>
      <stars>2</stars>
      <description>Viewable boredom</description>
   </movie>
</collection>

DOM-подобный анализ

Давайте сначала проанализируем наши XML-данные в виде дерева . Мы начинаем с требования библиотеки rexml / document ; часто для удобства мы делаем include REXML для импорта в пространство имен верхнего уровня.

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Now get the root element
root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]

# This will output all the movie titles.
xmldoc.elements.each("collection/movie"){ 
   |e| puts "Movie Title : " + e.attributes["title"] 
}

# This will output all the movie types.
xmldoc.elements.each("collection/movie/type") {
   |e| puts "Movie Type : " + e.text 
}

# This will output all the movie description.
xmldoc.elements.each("collection/movie/description") {
   |e| puts "Movie Description : " + e.text 
}

Это даст следующий результат —

Root element : New Arrivals
Movie Title : Enemy Behind
Movie Title : Transformers
Movie Title : Trigun
Movie Title : Ishtar
Movie Type : War, Thriller
Movie Type : Anime, Science Fiction
Movie Type : Anime, Action
Movie Type : Comedy
Movie Description : Talk about a US-Japan war
Movie Description : A schientific fiction
Movie Description : Vash the Stampede!
Movie Description : Viewable boredom

SAX-подобный анализ

Чтобы обработать те же данные, фильмы.xml , файл ориентированным на поток способом, мы определим класс слушателя, чьи методы будут являться целью для обратных вызовов от анализатора.

ПРИМЕЧАНИЕ. — Не рекомендуется использовать SAX-подобный синтаксический анализ для небольшого файла, это только для демонстрационного примера.

#!/usr/bin/ruby -w

require 'rexml/document'
require 'rexml/streamlistener'
include REXML

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*$/     # whitespace only
      abbrev = data[0..40] + (data.length > 40 ? "..." : "")
      puts "  text   :   #{abbrev.inspect}"
   end
end

list = MyListener.new
xmlfile = File.new("movies.xml")
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 schientific 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

Альтернативный способ просмотра XML — это XPath. Это своего рода псевдо-язык, который описывает, как найти конкретные элементы и атрибуты в документе XML, трактуя этот документ как логическое упорядоченное дерево.

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

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Info for the first movie found
movie = XPath.first(xmldoc, "//movie")
p movie

# Print out all the movie types
XPath.each(xmldoc, "//type") { |e| puts e.text }

# Get an array of all of the movie formats.
names = XPath.match(xmldoc, "//format").map {|x| x.text }
p names

Это даст следующий результат —

<movie title = 'Enemy Behind'> ... </>
War, Thriller
Anime, Science Fiction
Anime, Action
Comedy
["DVD", "DVD", "DVD", "VHS"]

XSLT и Ruby

Существует два парсера XSLT, которые может использовать Ruby. Краткое описание каждого приведено здесь.

Рубин-Sablotron

Этот парсер написан и поддерживается Масаёси Такахаши. Это написано в первую очередь для ОС Linux и требует следующих библиотек —

  • Sablot
  • Iconv
  • эмигрант

Вы можете найти этот модуль на Ruby-Sablotron .

XSLT4R

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

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

XSLT4R имеет следующий синтаксис —

ruby xslt.rb stylesheet.xsl document.xml [arguments]

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

Для получения полной информации о REXML Parser, пожалуйста, обратитесь к стандартной документации для REXML Parser Documentation .

Вы можете скачать XSLT4R из репозитория RAA .