REXML and XPath Confusion

Rubyists,

I am confused! (Nothing unusual there! :slight_smile:

Using XPath.match, I get an array of attributes. When I try to
match against this array, with what seems to be the same name,
it doesn’t match. Any ideas?

$ cat test.xml

<?xml version="1.0"?>

$ cat test.rb
require "rexml/xpath"
require "rexml/document"
include REXML

doc = Document.new File.new( “test.xml” )

panels = XPath.match( doc, “//panel/attribute::name” )
panels.each { |panel|
puts “panel --> [#{panel}]”
}
puts “-----”

doc.elements.each(“doc/section”) { |sect|
puts "sect --> #{sect.attributes[“name”]}"
sect.elements.each(“panel”) { |panel|
name = panel.attributes[“name”]
puts "panel --> [#{name}]"
puts (panels.include?(name)) ? “included” : “not found”
}
}

$ ruby test.rb
panel --> [overview]
panel --> [stuff]

···

sect --> intro
panel --> [overview]
not found
panel --> [stuff]
not found
sect --> foo
sect --> bar

Regards,

-mark.

REXML::Attributes# returns not a REXML::Attribute object
but a String object.

···

From: Mark Probert probertm@nortelnetworks.com
Subject: REXML and XPath Confusion
Date: Fri, 10 Jan 2003 00:47:30 +0900
Message-ID: 5.1.0.14.2.20030109104105.00b2e7d0@zcard04k.ca.nortel.com

$ cat test.rb
require “rexml/xpath”
require “rexml/document”
include REXML

doc = Document.new File.new( “test.xml” )

panels = XPath.match( doc, “//panel/attribute::name” )
panels.each { |panel|
puts “panel → [#{panel}]”
puts “panel class → [#{panel.class}]”
}
puts “-----”

doc.elements.each(“doc/section”) { |sect|
puts “sect → #{sect.attributes[“name”]}”
sect.elements.each(“panel”) { |panel|
name = panel.attributes[“name”]
puts “panel → [#{name}]”
puts “name class → [#{name.class}]”
puts (panels.include?(name)) ? “included” : “not found”
}
}

Regards,

======================
Kouhei Sutou
kou@cneti.net

Hi –

···

On Fri, 10 Jan 2003, Mark Probert wrote:

Rubyists,

I am confused! (Nothing unusual there! :slight_smile:

Using XPath.match, I get an array of attributes. When I try to
match against this array, with what seems to be the same name,
it doesn’t match. Any ideas?

$ cat test.xml

<?xml version="1.0"?>

$ cat test.rb
require “rexml/xpath”
require “rexml/document”
include REXML

doc = Document.new File.new( “test.xml” )

panels = XPath.match( doc, “//panel/attribute::name” )
panels.each { |panel|
puts “panel → [#{panel}]”
}
puts “-----”

doc.elements.each(“doc/section”) { |sect|
puts “sect → #{sect.attributes[“name”]}”
sect.elements.each(“panel”) { |panel|
name = panel.attributes[“name”]
puts “panel → [#{name}]”
puts (panels.include?(name)) ? “included” : “not found”
}
}

panels is an array of REXML::Attribute objects. That array won’t
include name, but it will include a panel whose value is the same as
name. You just have to dig a bit to get the value.

Replace your last line of code with:

puts panels.detect {|p| p.value == name } ? “included” : “not found”

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi.

···

At 12:47 AM 1/11/2003 +0900, David wrote:

panels is an array of REXML::Attribute objects. That array won’t
include name, but it will include a panel whose value is the same as
name. You just have to dig a bit to get the value.

Thank you. Much clearer now!

Regards,

-mark.

Hi.

REXML::Attributes# returns not a REXML::Attribute object
but a String object.

Please forgive my ignorance, I am not sure how that helps me.

panels = XPath.match( doc, "//panel/attribute::name" )

Appears to return an array of strings. When I do “panels.each”
it seems to be just strings. When I do “p panels” it doesn’t
appear to be strings. And I can’t match against strings.

What am I missing here?

Regards,

-mark.

···

At 01:16 AM 1/10/2003 +0900, Kouhei wrote:

Message-ID: 5.1.0.14.2.20030110095500.00b2eb98@zcard04k.ca.nortel.com

panels = XPath.match( doc, "//panel/attribute::name" )

Appears to return an array of strings. When I do “panels.each”
it seems to be just strings.

Really?
How about using Object#class?

I wrote in [ruby-talk:61021] :wink:

panels.each do |panel|
p panel.class
end

  		When I do "p panels" it doesn't

appear to be strings.

When you use puts you look REXML::Attribute#to_s.
When you use p you look REXML::Attribute#inspect.
Both are String.

  	 And I can't match against strings.

You can get a unnormalized attribute value as String
by using REXML::Attribute#value.
You can get a normalized attribute value as String
by using REXML::Attribute#to_s.

Regards,

kou

···

From: Mark Probert probertm@nortelnetworks.com
Subject: Re: REXML and XPath Confusion
Date: Sat, 11 Jan 2003 00:03:37 +0900

Hi.

···

At 01:19 AM 1/11/2003 +0900, kou wrote:

You can get a unnormalized attribute value as String
by using REXML::Attribute#value.
You can get a normalized attribute value as String
by using REXML::Attribute#to_s.

Thanks. That is the key …

Regards,

-mark.