# How to get REXML to return items in order?

**URL:** <https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595>\
**Category:** ruby-talk\
**Created:** [3 September 2005 21:16 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595 "2005-09-03T21:16:27Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ted2](https://avatars.discourse-cdn.com/v4/letter/t/77aa72/32.png) [@ted2](https://rubytalk.org/u/ted2)\
**Post date:** [3 September 2005 21:16 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/1 "2005-09-03T21:16:27Z")

</div>

Hi,

I'm new to Ruby and can't figure out why REXML isn't returning the elements  
in the order they appear in the document. Here's my code and the document.  
Any help appreciated.

Thanks,  
Ted

> **···**
>
> #==============================  
> # ruby  
> #==============================  
> xml = REXML::Document.new(File.open("test.html"));  
> xml.elements.each("//span[@class='c5']") do |element|  
> &nbsp;&nbsp;&nbsp;&nbsp;puts element  
> end
> 
> #==============================  
> # the "test.html" file  
> #==============================  
> \<html\>  
> \<body\>  
> \<a name="1"/\>  
> \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>1st Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
> \<a name="2"/\>  
> \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>2nd Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
> \<a name="3"/\>  
> \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>3rd Title\</b\>\</span\>\</td\>\</tr\>  
> \</table\>  
> \</body\>  
> \</html\>

---

<div class="post-metadata">

**Author:** ![Gavin\_Kistner2](https://avatars.discourse-cdn.com/v4/letter/g/b9e5f3/32.png) [@Gavin\_Kistner2](https://rubytalk.org/u/Gavin_Kistner2)\
**Post date:** [3 September 2005 23:40 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/2 "2005-09-03T23:40:05Z")

</div>

> I'm new to Ruby and can't figure out why REXML isn't returning the elements  
> in the order they appear in the document. Here's my code and the document.

I confirm the problem. Looks like a bug. If I remove some of the anchors, it works.  
(Off-topic - no need to use empty named anchors in your page - just use IDs on existing elements instead.)

Sliver:~/Desktop] gkistner$ cat tmp.rb  
code = \<\<ENDHTML  
\<html\>\<body\>  
\<a name="1"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>1st Title\</b\>\</span\>\</td\>\</tr\>\</

> 

\<a name="2"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>2nd Title\</b\>\</span\>\</td\>\</tr\>\</

> 

\<a name="3"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>3rd Title\</b\>\</span\>\</td\>\</tr\>\</

> 

\</body\>\</html\>  
ENDHTML

require 'rexml/document'  
xml = REXML::Document.new( code );  
xml.elements.each( "//span[@class='c5']" ) do |element|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts element  
end

[Sliver:~/Desktop] gkistner$ ruby -v tmp.rb  
ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.2]  
\<span class='c5'\>\<b\>3rd Title\</b\>\</span\>  
\<span class='c5'\>\<b\>1st Title\</b\>\</span\>  
\<span class='c5'\>\<b\>2nd Title\</b\>\</span\>

> **···**
>
> On Sep 3, 2005, at 3:16 PM, ted wrote:

---

<div class="post-metadata">

**Author:** ![ted2](https://avatars.discourse-cdn.com/v4/letter/t/77aa72/32.png) [@ted2](https://rubytalk.org/u/ted2)\
**Post date:** [4 September 2005 00:31 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/3 "2005-09-04T00:31:28Z")

</div>

Thanks Gavin. Unfortunately I can't remove the anchors. The html is just a  
sample of the documents (not my docs) that I'm given to parse. Someone on  
IRC mentioned that XPath 1.0 doesn't guarantee the order of elements.

"Gavin Kistner" \<gavin@refinery.com\> wrote in message  
news:6A73B666-6668-430A-8C58-96DC8294A970@refinery.com...

> **···**
>
> > On Sep 3, 2005, at 3:16 PM, ted wrote:
> > 
> > > I'm new to Ruby and can't figure out why REXML isn't returning the  
> > > elements  
> > > in the order they appear in the document. Here's my code and the  
> > > document.
> > 
> > I confirm the problem. Looks like a bug. If I remove some of the  
> > anchors, it works.  
> > (Off-topic - no need to use empty named anchors in your page - just  
> > use IDs on existing elements instead.)
> > 
> > Sliver:~/Desktop] gkistner$ cat tmp.rb  
> > code = \<\<ENDHTML  
> > \<html\>\<body\>  
> > \<a name="1"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>1st Title\</b\>\</span\>\</td\>\</tr\>\</  
> > \>  
> > \<a name="2"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>2nd Title\</b\>\</span\>\</td\>\</tr\>\</  
> > \>  
> > \<a name="3"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>3rd Title\</b\>\</span\>\</td\>\</tr\>\</  
> > \>  
> > \</body\>\</html\>  
> > ENDHTML
> > 
> > require 'rexml/document'  
> > xml = REXML::Document.new( code );  
> > xml.elements.each( "//span[@class='c5']" ) do |element|  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts element  
> > end
> > 
> > [Sliver:~/Desktop] gkistner$ ruby -v tmp.rb  
> > ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.2]  
> > \<span class='c5'\>\<b\>3rd Title\</b\>\</span\>  
> > \<span class='c5'\>\<b\>1st Title\</b\>\</span\>  
> > \<span class='c5'\>\<b\>2nd Title\</b\>\</span\>

---

<div class="post-metadata">

**Author:** ![daz](https://avatars.discourse-cdn.com/v4/letter/d/87869e/32.png) [@daz](https://rubytalk.org/u/daz)\
**Post date:** [4 September 2005 01:41 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/4 "2005-09-04T01:41:26Z")

</div>

Gavin Kistner wrote:

> \> I'm new to Ruby and can't figure out why REXML isn't returning the  
> \> elements  
> \> in the order they appear in the document. Here's my code and the  
> \> document.
> 
> I confirm the problem. Looks like a bug. [...]

.... and it's fixed in CVS for 1.8.3

If you need this now, you could download the later version here:  
[http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rexml/rexml.tar.gz?only\_with\_tag=ruby\_1\_8;tarball=1](http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rexml/rexml.tar.gz?only_with_tag=ruby_1_8;tarball=1)

to e.g. "C:\Ruby\TEMP" then change the lookup path at the top of your script.

$:.unshift('C:/Ruby/TEMP') # for rexml fixes  
require 'rexml/document'  
xml = REXML::Document.new(DATA)  
xml.elements.each("//span[@class='c5']") do |element|  
&nbsp;&nbsp;puts element  
end

#-\> \<span class='c5'\>\<b\>1st Title\</b\>\</span\>  
#-\> \<span class='c5'\>\<b\>2nd Title\</b\>\</span\>  
#-\> \<span class='c5'\>\<b\>3rd Title\</b\>\</span\>

\_\_END\_\_  
\<html\>  
\<body\>  
\<a name="1"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>1st Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
\<a name="2"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>2nd Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
\<a name="3"/\>  
\<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>3rd Title\</b\>\</span\>\</td\>\</tr\>  
\</table\>  
\</body\>  
\</html\>

daz

> **···**
>
> > On Sep 3, 2005, at 3:16 PM, ted wrote:

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [4 September 2005 01:19 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/5 "2005-09-04T01:19:34Z")

</div>

Hi --

> **···**
>
> On Sun, 4 Sep 2005, ted wrote:
> 
> > Thanks Gavin. Unfortunately I can't remove the anchors. The html is just a  
> > sample of the documents (not my docs) that I'm given to parse. Someone on  
> > IRC mentioned that XPath 1.0 doesn't guarantee the order of elements.
> 
> I would be astonished if Sean Russell had combed through the 1.0 spec  
> to find some loophole that made it plausible to have an iteration not  
> follow document order. I could be wrong but I think it's more likely  
> a REXML bug.
> 
> David
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![ted2](https://avatars.discourse-cdn.com/v4/letter/t/77aa72/32.png) [@ted2](https://rubytalk.org/u/ted2)\
**Post date:** [4 September 2005 04:11 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/6 "2005-09-04T04:11:27Z")

</div>

Thanks daz.

"daz" \<dooby@d10.karoo.co.uk\> wrote in message  
news:YTWdnRhBUv9S0ofeSa8jmw@karoo.co.uk...

> **···**
>
> > Gavin Kistner wrote:
> > 
> > > On Sep 3, 2005, at 3:16 PM, ted wrote:  
> > > \> I'm new to Ruby and can't figure out why REXML isn't returning the  
> > > \> elements  
> > > \> in the order they appear in the document. Here's my code and the  
> > > \> document.
> > > 
> > > I confirm the problem. Looks like a bug. [...]
> > 
> > ... and it's fixed in CVS for 1.8.3
> > 
> > If you need this now, you could download the later version here:  
> > [http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rexml/rexml.tar.gz?only\_with\_tag=ruby\_1\_8;tarball=1](http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/lib/rexml/rexml.tar.gz?only_with_tag=ruby_1_8;tarball=1)
> > 
> > to e.g. "C:\Ruby\TEMP" then change the lookup path at the top of your  
> > script.
> > 
> > $:.unshift('C:/Ruby/TEMP') # for rexml fixes  
> > require 'rexml/document'  
> > xml = REXML::Document.new(DATA)  
> > xml.elements.each("//span[@class='c5']") do |element|  
> > puts element  
> > end
> > 
> > #-\> \<span class='c5'\>\<b\>1st Title\</b\>\</span\>  
> > #-\> \<span class='c5'\>\<b\>2nd Title\</b\>\</span\>  
> > #-\> \<span class='c5'\>\<b\>3rd Title\</b\>\</span\>
> > 
> > \_\_END\_\_  
> > \<html\>  
> > \<body\>  
> > \<a name="1"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>1st Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
> > \<a name="2"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>2nd Title\</b\>\</span\>\</td\>\</tr\>\</table\>  
> > \<a name="3"/\>  
> > \<table\>\<tr\>\<td\>\<span class="c5"\>\<b\>3rd Title\</b\>\</span\>\</td\>\</tr\>  
> > \</table\>  
> > \</body\>  
> > \</html\>
> > 
> > daz

---

<div class="post-metadata">

**Author:** ![Dan\_Kohn](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@Dan\_Kohn](https://rubytalk.org/u/Dan_Kohn)\
**Post date:** [15 September 2005 07:01 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/7 "2005-09-15T07:01:34Z")

</div>

I just wanted to mention that I encountered the same bug and that the  
new version of the library fixed it for me. Thank you very much for  
the clear instructions. If only for pay products had support that was  
this good....

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- dan

> **···**
>
> --  
> Dan Kohn \<[mailto:dan@dankohn.com](mailto:dan@dankohn.com)\>  
> \<[http://www.dankohn.com/](http://www.dankohn.com/)\> \<tel:+1-415-233-1000\>

---

<div class="post-metadata">

**Author:** ![Dan\_Kohn](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@Dan\_Kohn](https://rubytalk.org/u/Dan_Kohn)\
**Post date:** [15 September 2005 19:46 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/8 "2005-09-15T19:46:34Z")

</div>

Daz, there's a bug in the CVS version of REXML. The following code  
produces the error below, but works perfectly with the default 1.8.2  
REXML (i.e., when I comment out the first line).

> ruby rexmlbug.rb

C:/Dan/dev/rexml/xpath\_parser.rb:157:in `expr': undefined method  
`delete\_if' for nil:NilClass (NoMethodError)  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:481:in `d\_o\_s'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:478:in `each\_index'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:478:in `d\_o\_s'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:469:in `descendant\_or\_self'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:314:in `expr'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:125:in `match'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath\_parser.rb:56:in `parse'  
&nbsp;&nbsp;from C:/Dan/dev/rexml/xpath.rb:53:in `each'  
&nbsp;&nbsp;from rexmlbug.rb:28

> Exit code: 1

$:.unshift('C:/Dan/dev') # for rexml fixes  
require "rexml/document"  
include REXML  
string = \<\<EOF  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<html\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<td class="t4"\>\<a href="javascript:lu('OZ')"\>OZ\</a\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0204 F Class  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<a href="/cgi/get?apt:uMl8TIcSlHI\*itn/airports/ICN,itn/air/mp"\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ICN\</a\> to \<a  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;href="/cgi/get?apt:uMl8TIcSlHI\*itn/airports/LAX,itn/air/mp"\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LAX\</a\>\</td\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<tr\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<td class="t4"\>\<font color="white"\>UNITED\</font\>\</td\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<td colspan="4" align="right"\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<strong\>48,164\</strong\>\</td\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\</tr\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<tr\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<td class="t4"\>\<font color="white"\>Star  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Alliance\</font\>\</td\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<td colspan="4" align="right"\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<strong\>49,072\</strong\>\</td\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\</tr\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\</html\>  
EOF

doc = Document.new string.gsub!(/\s+|&nbsp;/," ")  
array = Array.new  
XPath.each( doc, "//td[@colspan='4']/preceding-sibling::td/child::\*") {

> cell\>

&nbsp;&nbsp;array \<\< cell.texts.to\_s }  
puts array

---

<div class="post-metadata">

**Author:** ![daz](https://avatars.discourse-cdn.com/v4/letter/d/87869e/32.png) [@daz](https://rubytalk.org/u/daz)\
**Post date:** [17 September 2005 01:16 UTC](https://rubytalk.org/t/how-to-get-rexml-to-return-items-in-order/20595/9 "2005-09-17T01:16:36Z")

</div>

Dan Kohn wrote:

> Daz, there's a bug in the CVS version of REXML.  
> The following code produces the error below, but works  
> perfectly with the default 1.8.2 REXML [...]

Thanks Dan.

The REXML code in that area looks quite "fluid" and  
there are clear warnings to "turn away" (which I heeded ;).

I've filed a bug report which you might want to check over  
and then keep a watch on.

[http://www.germane-software.com/projects/rexml/ticket/32](http://www.germane-software.com/projects/rexml/ticket/32)

Cheers,

daz
