Unit Testing with REXML questions

P

Peter Fitzgibbons

Hello all,

I'm using REXML to build some XML from a rails app. I'm unit testing
the output also using REXML... and I have these questions :

Given

<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>

I want to use XPath to tell me how many <d> there are under <a> ?

I want to use XPath to iterate the _names_ of the items under <d>
(Does this make sense in XML World. This one is not necessarily a
requirement, but I uncovered this need while experimenting in IRB.) ?

Thanks in advance!
Peter Fitzgibbons
 
J

Jeff Wood

------=_Part_16167_15320578.1129291364849
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

one specific <a> or all <a> tags???
But, you should be able to do:
root.elements( "/a/d" ).size
and that should return the count of ALL <d> elements under any <a> tag
root.elements( "/a[1]/d" ).size
should return the count of <d> elements under the first <a> tag ( it does
appear that the index operator in xpath is one-based not zero-based ).
Hope that helps.
j.

Hello all,

I'm using REXML to build some XML from a rails app. I'm unit testing
the output also using REXML... and I have these questions :

Given

<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>

I want to use XPath to tell me how many <d> there are under <a> ?

I want to use XPath to iterate the _names_ of the items under <d>
(Does this make sense in XML World. This one is not necessarily a
requirement, but I uncovered this need while experimenting in IRB.) ?

Thanks in advance!
Peter Fitzgibbons


--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

------=_Part_16167_15320578.1129291364849--
 
P

Peter Fitzgibbons

HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/d

I want this to return 1 (the number of "d" elements in the list)
 
P

Peter Fitzgibbons

Ah, well I now understand...
using xml.elements[] does not return the same object as
REXML::XPath.match, which returns an array of results.

Thank you.
 
U

umitanuki

Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin = <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml = REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki
 
J

Jeff Wood

Peter,

Actually... i don't understand why you got "5" when you did size...
that was one element.

And yes, an element contains it's children ... but they aren't going
to be iterated over unless you did something like /a/d/* or something
like that.

what do you get when you run

count =3D 0 ; xml.elements( '/a/d' ).each { count +=3D 1 ) ; puts count

... of course umitanuki's to_a should also simply return an array of 1 leng=
th.

j.

Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki


Peter said:
HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/d

I want this to return 1 (the number of "d" elements in the list)
 
U

umitanuki

Hi Jeff, and Peter,

I also got "5" with this code:

xml.elements['/a/d'].size

And then I checked your code like:

xml.elements('/a/d') ,

it failed with message
" in 'elements': wrong number of arguments(1 for 0) (Argument Error) ".

Is it the difference of REXML version??
My REXML is 3.1.2.1.

Regards,


umitanuki


Jeff said:
Peter,

Actually... i don't understand why you got "5" when you did size...
that was one element.

And yes, an element contains it's children ... but they aren't going
to be iterated over unless you did something like /a/d/* or something
like that.

what do you get when you run

count = 0 ; xml.elements( '/a/d' ).each { count += 1 ) ; puts count

... of course umitanuki's to_a should also simply return an array of 1 length.

j.

Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin = <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml = REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki


Peter said:
HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin = <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml = REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/d

I want this to return 1 (the number of "d" elements in the list)
 
P

Peter Fitzgibbons

Hi Jeff, and Peter,

I also got "5" with this code:

xml.elements['/a/d'].size

And then I checked your code like:

xml.elements('/a/d') ,

it failed with message
" in 'elements': wrong number of arguments(1 for 0) (Argument Error) ".

Is it the difference of REXML version??
My REXML is 3.1.2.1.

Regards,


umitanuki


Jeff said:
Peter,

Actually... i don't understand why you got "5" when you did size...
that was one element.

And yes, an element contains it's children ... but they aren't going
to be iterated over unless you did something like /a/d/* or something
like that.

what do you get when you run

count =3D 0 ; xml.elements( '/a/d' ).each { count +=3D 1 ) ; puts count

... of course umitanuki's to_a should also simply return an array of 1 = length.

j.

Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki


Peter Fitzgibbons wrote:

HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/d

I want this to return 1 (the number of "d" elements in the list)

My code was :

puts xml.elements['/a/d'].size

in previous post.
 
J

Jeff Wood

My mistake

I meant for the param to be sent to "each"

count =3D 0
xml.elements.each( "/a/d" ) { count +=3D 1 }
puts count

j.

Hi Jeff, and Peter,

I also got "5" with this code:

xml.elements['/a/d'].size

And then I checked your code like:

xml.elements('/a/d') ,

it failed with message
" in 'elements': wrong number of arguments(1 for 0) (Argument Error) ".

Is it the difference of REXML version??
My REXML is 3.1.2.1.

Regards,


umitanuki


Jeff said:
Peter,

Actually... i don't understand why you got "5" when you did size...
that was one element.

And yes, an element contains it's children ... but they aren't going
to be iterated over unless you did something like /a/d/* or somethin= g
like that.

what do you get when you run

count =3D 0 ; xml.elements( '/a/d' ).each { count +=3D 1 ) ; puts cou= nt

... of course umitanuki's to_a should also simply return an array of = 1 length.

j.


Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki


Peter Fitzgibbons wrote:

HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin =3D <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml =3D REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/= d

I want this to return 1 (the number of "d" elements in the list)

My code was :

puts xml.elements['/a/d'].size

in previous post.
 
U

umitanuki

I didn't know such a code but it's seemed so useful.
Tanks,


umitanuki

Jeff said:
My mistake

I meant for the param to be sent to "each"

count = 0
xml.elements.each( "/a/d" ) { count += 1 }
puts count

j.

Hi Jeff, and Peter,

I also got "5" with this code:

xml.elements['/a/d'].size

And then I checked your code like:

xml.elements('/a/d') ,

it failed with message
" in 'elements': wrong number of arguments(1 for 0) (Argument Error) ".

Is it the difference of REXML version??
My REXML is 3.1.2.1.

Regards,


umitanuki


Jeff Wood wrote:

Peter,

Actually... i don't understand why you got "5" when you did size...
that was one element.

And yes, an element contains it's children ... but they aren't going
to be iterated over unless you did something like /a/d/* or something
like that.

what do you get when you run

count = 0 ; xml.elements( '/a/d' ).each { count += 1 ) ; puts count

... of course umitanuki's to_a should also simply return an array of 1 length.

j.



Hi Peter,

What you want is to get the array of specific nodes, isn't it??
If it's true, see code below:

xmltest.rb :
require 'rexml/document'

xmlin = <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml = REXML::Document.new(xmlin)
puts xml.elements.to_a('/a/d')

--
then, you can iterate with the nodes of 'd', including knowing
the number of 'd' nodes with '.size' method, right??

Regards,


umitanuki


Peter Fitzgibbons wrote:


HI Jeff,

xmltest.rb :
require 'rexml/document'

xmlin = <<EOD
<a>
<b>one</b>
<c>two</c>
<d>
<e>three</e>
<f>four</f>
</d>
</a>
EOD

xml = REXML::Document.new(xmlin)
puts xml.elements['/a/d'].size
puts xml.elements['/a/d']


output :
5
<d>
<e>three</e>
<f>four</f>
</d>

xml.elements['/a/d'] returns the entire xml tree under/including /a/d

I want this to return 1 (the number of "d" elements in the list)
My code was :

puts xml.elements['/a/d'].size

in previous post.
 
G

Gavin Kistner

count = 0 ; xml.elements( '/a/d' ).each { count += 1 ) ; puts count

Because the each method returns the collection, you can actually just
do this (odd-looking) hack:
puts xml.elements.each('/a/d'){}.size

(The block is required, but may be empty.)
 
J

Jeff Wood

true.

Because the each method returns the collection, you can actually just
do this (odd-looking) hack:
puts xml.elements.each('/a/d'){}.size

(The block is required, but may be empty.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top