REXML - text nodes

I’m testing the REXML module (Ruby 1.8).

I have this simple XML ducument “test.xml”:

vxml:prompt
You have chosen to stay at the
<vxml:value expr=“field_hotel”/> tonight
</vxml:prompt>

which I analyse with this script:

require "rexml/document"
include REXML

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

doc.elements.each(“vxml:prompt”) do |element|
puts “Text:” + element.text
element.elements.each() do |child|
puts “SubElement:” + child.name
end
end

The output is
Text:
You have chosen to stay at the
SubElement:value

The “text” method only returns the first “text node” in the prompt
element,
and there is only one child element. So apperantly text nodes are not
part
of the child elements array…

How do I access the remaining text?

I assume this is possible, but unfortunately the
http://www.germane-software.com/software/rexml seems to
be down today, so I can’t get to the documentation.

Cheers
Jesper

The “text” method only returns the first “text node” in the prompt
element,

It returns the first text child of the given node:

" text( path = nil )

A convenience method which returns the String value of the first child
text element, if one exists, and nil otherwise.

Note that an element may have multiple Text elements, perhaps
separated by other children. Be aware that this method only returns
the first Text node."

and there is only one child element. So apperantly text nodes are not
part
of the child elements array…

How do I access the remaining text?

They are children of the node, but you have explicitly called
Element#elements which filters out the non-text children:

[documentation for REXML::Elements]

each( xpath=nil, &block) {|e if e.kind_of? Element }| …}

Iterates through all of the child Elements, optionally filtering them
by a given XPath
xpath: optional. If supplied, this is a String XPath, and is used to
filter the children, so that only matching children are yielded. Note
that XPaths are automatically filtered for Elements, so that
non-Element children will not be yielded

…and text children are REXML::Text, not REXML::Element, so are skipped.

However you can use Element#each to iterate over all the children, both Text
and Element:

require “rexml/document”
include REXML

file=File.new(“test2.xml”)
doc=Document.new file

doc.each do |element|
element.each do |child|
if child.is_a?(REXML::Text)
puts “Text: #{child.to_s.inspect}”
else
puts “SubElement: #{child.name}”
end
end
end

Regards,

Brian.

···

On Wed, Aug 13, 2003 at 07:46:26PM +0900, Jesper Olsen wrote:

Thanks Brian - good answer.

Jesper

Brian Candler B.Candler@pobox.com wrote in message news:20030813121450.A72531@linnet.org

···

On Wed, Aug 13, 2003 at 07:46:26PM +0900, Jesper Olsen wrote: