REXML and XPath


#1

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:

Gecamin Paseo Bulnes 197 Fernando Poblete .....

And I want to produce HTML as follows:

Name: Gecamin

Address: Paseo Bulnes 197

Employees

First Name: Fernando

Last Name: Poblete

.... ...

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

First Name: Fer

I know XPath is the best answer but I haven’t been able to figure it
out. Could anyone give me some tips? Thanks.


#2

For your first problem, it sounds like you should be using XSLT:
http://greg.rubyfr.net/pub/packages/ruby-xslt/files/README.html

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-


#3

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