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