Forum: Ruby on Rails REXML and XPath

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
D038c5d90a88bf31c73b300f73860126?d=identicon&s=25 Fernando Poblete (fipa)
on 2007-05-04 18:41
Hi. I'm working with XML and REXML and I could use some help in two
particular issues:
First, I want to display a REXML::Document object. I'm creating the
object from a string that contains a valid xml, something like:

   <address>Paseo Bulnes 197</address>

And I want to produce HTML as follows:

<div class='company'>
    <p>Name: Gecamin</p>
    <p>Address: Paseo Bulnes 197</p>
    <div class='employees'>
         <div class='employee'>
               <p>First Name: Fernando</p>
               <p>Last Name: Poblete</p>

The second thing is that I'm working with two versions of a same record,
each one in a different REXML::Document object. So I have
@old_record_xml and @new_record_xml and want to compare them in order to
indicate which fields has changed from old version to new version. So if
an employee's first name has been changedn I want to produce HTML like

<p class='updated'>First Name: Fer</p>

I know XPath is the best answer but I haven't been able to figure it
out. Could anyone give me some tips? Thanks.
8bc543795b502900b5333aea73ad5533?d=identicon&s=25 Eden Li (edenli)
on 2007-05-05 06:45
(Received via mailing list)
For your first problem, it sounds like you should be using XSLT:

For your second, I've never heard of XPath being used for this, but I
could be wrong.  It sounds like you'll just have to write your own
compare function that will emit nodes that have changed.

On May 5, 12:41 am, Fernando Poblete <rails-mailing-l...@andreas-
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-05-05 17:13
(Received via mailing list)
Fernando Poblete wrote:

> Hi. I'm working with XML and REXML and I could use some help in two
> particular issues:
> First, I want to display a REXML::Document object.

Last time I checked, Ruby had incomplete native XSLT support. You need
get either msxsl.exe by Microsoft or xsltproc by everyone else. Then
your XML thru an XSLT template to re-render everything in XHTML.

Below my sig is a snip of code that detects which one you have and calls

To diff XML, you could google for "diff XML", "XMLunit", or "XSLTunit".
have not tried either, but as diffing content is a major aspect of
the XSLTunit ought to show how to do it.

  "Test Driven Ajax (on Rails)"
  assert_xpath, assert_javascript, & assert_ajax

$win32Exts = %w{.exe .com .bat}

   # Adapted from Michael Granger's FileWhich on RubyGarden

 def which(prog, path=ENV['PATH'])

  path.split(File::PATH_SEPARATOR).each {|dir|
   # Windows checks against specific extensions
    ext = $win32Exts.find{|ext|
       if prog.include?('.') # Assume extension already included
        f = File.join(dir,prog)
        f = File.join(dir,prog+ext)
       File.executable?(f) && !
    if ext
       # Use backslashes, not forward slashes
       if prog.include?('.') # Assume extension already included
        f = File.join( dir, prog ).gsub(/\//,'\\')
        f = File.join( dir, prog + ext ).gsub(/\//,'\\')
       return f
    f = File.join(dir,prog)
    # Avoid /usr/lib/ruby, for example
    if File.executable?(f) && !
       return File::join( dir, prog )


def callXsl(xslFile, xmlFile, param = {})

  msxsl = which('msxsl')
  xsltproc = which('xsltproc')

  if xsltproc != nil then
    params = ''

    param.each { |p,v|
      params += "--param #{p} \"'#{v}'\" "

    xhtml = `#{xsltproc} #{params} #{xslFile} #{xmlFile} 2>&1`
    return xhtml

  elsif msxsl != nil then
    params = ''

    param.each { |p,v|
      params += p
      params += '="'
      params += v
      params += '" '

    msxsl.gsub!'\\\\', '/'
    cmd = "#{msxsl} #{xmlFile} #{xslFile} #{params}"
    xhtml = `#{cmd} 2>&1`
    return xhtml
    return 'please install either msxsl or xsltproc'


def _Transform(xmlFile, xslFile, param)
  return callXsl(xslFile, xmlFile, param = {})
This topic is locked and can not be replied to.