Forum: Ruby on Rails REXML and XPath

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Fernando P. (Guest)
on 2007-05-04 20: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:

<company>
   <name>Gecamin</name>
   <address>Paseo Bulnes 197</address>
   <employees>
        <employee>
             <first-name>Fernando</first-name>
             <last-name>Poblete</last-name>
        </employee>
        <employee>
              .....
        </employee>
    </employees>
</company>

And I want to produce HTML as follows:

<div class='company'>
    <p>Name: Gecamin</p>
    <p>Address: Paseo Bulnes 197</p>
    <div class='employees'>
         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.
Eden L. (Guest)
on 2007-05-05 08:45
(Received via mailing list)
For your first problem, it sounds like you should be using XSLT:
http://greg.rubyfr.net/pub/packages/ruby-xslt/file...

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 P. <rails-mailing-l...@andreas-
Phlip (Guest)
on 2007-05-05 19:13
(Received via mailing list)
Fernando P. 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
to
get either msxsl.exe by Microsoft or xsltproc by everyone else. Then
pipe
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
it
correctly.

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

--
  Phlip
  http://www.oreilly.com/catalog/9780596510657/
  "Test Driven Ajax (on Rails)"
  assert_xpath, assert_javascript, & assert_ajax

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

   # Adapted from Michael G.'s FileWhich on RubyGarden

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

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

 end


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
  else
    return 'please install either msxsl or xsltproc'
  end

end


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