Расширяемый язык разметки (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 .