Tutorial de Ruby XML, XSLT y XPath


¿Qué es XML?

XML significa Lenguaje de Marcado Extensible (eXtensible Markup Language).

El Lenguaje de Marcado Extensible, un subconjunto del Lenguaje Estándar de Marcado Generalizado, es un lenguaje de marcado utilizado para marcar documentos electrónicos y darles estructura.

Se puede utilizar para marcar datos y definir tipos de datos. Es un lenguaje fuente que permite a los usuarios definir sus propios lenguajes de marcado. Es muy adecuado para la transmisión por la World Wide Web, ya que proporciona un método uniforme para describir e intercambiar datos estructurados independientes de aplicaciones o proveedores.

Para más contenido, consulte nuestroTutorial de XML


Estructura y API del analizador XML

Los analizadores de XML son principalmente de dos tipos: DOM y SAX.

  • El analizador SAX se basa en el manejo de eventos. Necesita escanear el documento XML de principio a fin. Durante el escaneo, cada vez que encuentra una estructura sintáctica, llama al controlador de eventos de esa estructura sintáctica específica y envía un evento a la aplicación.
  • DOM es el análisis del Modelo de Objetos del Documento. Construye la estructura sintáctica jerárquica del documento y crea un árbol DOM en memoria. Los nodos del árbol DOM se identifican en forma de objetos. Una vez completado el análisis del documento, todo el árbol DOM del documento se coloca en la memoria.

Analizar y crear XML en Ruby

En Ruby, para el análisis de documentos XML se puede utilizar la biblioteca REXML.

La biblioteca REXML es un kit de herramientas XML de Ruby, escrita en lenguaje Ruby puro y que cumple con la especificación XML 1.0.

Desde la versión 1.8 de Ruby en adelante, la biblioteca estándar de Ruby incluirá REXML.

La ruta de la biblioteca REXML es: rexml/document

Todos los métodos y clases están encapsulados en un módulo REXML.

El analizador REXML tiene las siguientes ventajas sobre otros analizadores:

  • 100% escrito en Ruby.
  • Se puede aplicar a analizadores SAX y DOM.
  • Es ligero, con menos de 2000 líneas de código.
  • Métodos y clases fáciles de entender.
  • Basado en la API SAX2 y con soporte completo de XPath.
  • Se instala con Ruby, sin necesidad de instalación adicional.

El siguiente es el código XML del ejemplo, guárdelo como movies.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>

Analizador DOM

Primero analicemos los datos XML. Para ello, introducimos la biblioteca rexml/document. Normalmente podemos incluir REXML en el espacio de nombres de nivel superior:

Ejemplo

#!/usr/bin/ruby -w require 'rexml/document' include REXML xmlfile = File.new("movies.xml") xmldoc = Document.new(xmlfile) #Obtener el elemento root root = xmldoc.root puts "Root element : " + root.attributes["shelf"] #Lo siguiente imprimirá los títulos de las películas. xmldoc.elements.each("collection/movie"){ |e| puts "Movie Title : " + e.attributes["title"] } #Lo siguiente imprimirá todos los géneros de películas. xmldoc.elements.each("collection/movie/type") { |e| puts "Movie Type : " + e.text } #Lo siguiente imprimirá todas las descripciones de las películas. xmldoc.elements.each("collection/movie/description") { |e| puts "Movie Description : " + e.text }

El resultado de salida del ejemplo anterior es:

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-like Parsing:

Analizador SAX

Para procesar el mismo archivo de datos: movies.xml. No se recomienda el análisis SAX para un archivo pequeño. El siguiente es un ejemplo sencillo:

Ejemplo

#!/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)

El resultado de salida anterior es:

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 y Ruby

Podemos usar XPath para consultar XML. XPath es un lenguaje para buscar información en documentos XML (ver:Tutorial de XPath).

XPath es el Lenguaje de Rutas XML. Es un lenguaje que se utiliza para determinar la posición de una parte en un documento XML (subconjunto del Lenguaje Estándar de Marcado Generalizado). XPath se basa en la estructura de árbol del XML y proporciona la capacidad de buscar nodos en el árbol de estructura de datos.

Ruby admite XPath a través de la clase XPath de REXML, que se basa en el análisis de árbol (Modelo de Objetos del Documento).

Ejemplo

#!/usr/bin/ruby -w require 'rexml/document' include REXML xmlfile = File.new("movies.xml") xmldoc = Document.new(xmlfile) #La información de la primera película movie = XPath.first(xmldoc, "//movie") p movie #Imprimir todos los géneros de películas XPath.each(xmldoc, "//type") { |e| puts e.text } #Obtener los tipos de todos los formatos de películas, devuelve un array names = XPath.match(xmldoc, "//format").map {|x| x.text } p names

El resultado de salida del ejemplo anterior es:

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

XSLT y Ruby

En Ruby hay dos analizadores XSLT, a continuación se proporciona una breve descripción:

Ruby-Sablotron

Este analizador fue escrito y mantenido por Masayoshi Takahash. Está escrito principalmente para el sistema operativo Linux y requiere las siguientes bibliotecas:

  • Sablot
  • Iconv
  • Expat

Puedes, enRuby-Sablotronencontrar estas bibliotecas.

XSLT4R

XSLT4R fue escrito por Michael Neumann. XSLT4R se utiliza para la interacción sencilla con la línea de comandos y puede ser utilizado por aplicaciones de terceros para transformar documentos XML.

XSLT4R requiere la operación XMLScan, que está incluida en el archivo XSLT4R. Es un módulo 100% Ruby. Estos módulos se pueden instalar utilizando el método estándar de instalación de Ruby (es decir, ruby install.rb).

La sintaxis de XSLT4R es la siguiente:

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

Si desea utilizar XSLT4R en su aplicación, puede introducir XSLT e ingresar los parámetros que necesite. El ejemplo es el siguiente:

Ejemplo

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 )

Más información

Otras extensiones