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.

hi,
I am using REXML
I want to get all the attributes under an element. Just imagine that I
know the element name but not the attribute names.
say <element att1="x" att2="y" att3="3"/> and so on as many attributes
that can be.
I need to get all the attributes under the element. How shall I do it.
I looked into REXML doc that provides
"doc.root.attributes.each {|name, value| puts name+" => "+value }"
But I am able to use this only on root element, and does not work on
child or subchild elements.
Please let me know how can I do that.
Regards,
Naresh

Naresh R. wrote:
> hi,>> I am using REXML>> I want to get all the attributes under an element. Just imagine that I> know the element name but not the attribute names.>> say <element att1="x" att2="y" att3="3"/> and so on as many attributes> that can be.>> I need to get all the attributes under the element. How shall I do it.>> I looked into REXML doc that provides> "doc.root.attributes.each {|name, value| puts name+" => "+value }">> But I am able to use this only on root element, and does not work on> child or subchild elements.>> Please let me know how can I do that.>> Regards,> Naresh
require 'rexml/document'
include REXML
xml = <<ENDSTRING
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body att1="x" att2="y">Don't forget me this weekend!</body>
</note>
ENDSTRING
doc = Document.new xml
el_name = "body"
matching_elements = XPath.match(doc, "//#{el_name}")
matching_elements.each do |el|
attrs = el.attributes
attrs.each_key do |key|
puts attrs[key]
end
end
--output:--
x
y

Naresh R. wrote:
> Thank you for the solution, it almost worked to me, but when I apply it> on my xml document I am getting the output from reverse order, why so?> <REMOVE_1 header='req_line' mname='InVIte'> uri='tel:removed_email_address@domain.invalid'/>> I applied the code for the element "REMOVE_1" and observe the following> as the output.>> -----output------> tel:removed_email_address@domain.invalid> InVIte> req_line> -----------------
XML has a concept of document order, but not of attribute order within
one tag.
XML readers are (apparently) not required to remember there order.
Next, the attributes come in a Hash, and this has a BUG (!) which will
be FIXED
(!) in the next Ruby versions. It can't preserve the order you inserted
its keys.
Until then, your own code must put the keys into the order you need. Try
element.attributes.to_a.sort
to put them into asciibetic order, for example.

Phlip wrote:
> Naresh R. wrote:>> Next, the attributes come in a Hash, and this has a BUG (!) which will> be FIXED> (!) in the next Ruby versions. It can't preserve the order you inserted> its keys.>
Hmm. A bug is when a language doesn't operate as described:
----
p. 46, pickaxe 2:
[a hash's] elements are not ordered, so you can not easily use a hash as
a stack or a queue.
p. 492
The order in which keys and/or values are returned by the various
iterators over hash contents may seem arbitrary and will generally not
be in insertion order.
----
$ ri Hash
------------------------------------------------------------ Class: Hash
A +Hash+ is a collection of key-value pairs. It is similar to an
+Array+, except that indexing is done via arbitrary keys of any
object type, not an integer index. The order in which you traverse
a hash by either key or value may seem arbitrary, and will
generally not be in the insertion order.
Hashes have a _default value_ that is returned when accessing keys
that do not exist in the hash. By default, that value is +nil+.
------------------------------------------------------------------------
Also, in many other languages dictionaries or associative arrays are
unordered collections.