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
Jeff_Wood
(Jeff Wood)
14 October 2005 12:02
2
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.
···
On 10/14/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
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
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)
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.
umitanuki
(umitanuki)
16 October 2005 13:27
5
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)
Jeff_Wood
(Jeff Wood)
16 October 2005 15:07
6
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.
···
On 10/16/05, umitanuki <yasagure@umitanuki.net> wrote:
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)
>
>
>
--
"http://ruby-lang.org -- do you ruby?"
Jeff Wood
umitanuki
(umitanuki)
17 October 2005 14:55
7
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.
On 10/16/05, umitanuki <yasagure@umitanuki.net> wrote:
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)
--
"http://ruby-lang.org -- do you ruby?"
Jeff Wood
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.)
···
On Oct 16, 2005, at 9:07 AM, Jeff Wood wrote:
count = 0 ; xml.elements( '/a/d' ).each { count += 1 ) ; puts count
My code was :
puts xml.elements['/a/d'].size
in previous post.
···
On 10/17/05, umitanuki <yasagure@umitanuki.net> wrote:
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.
>
> On 10/16/05, umitanuki <yasagure@umitanuki.net> wrote:
>
>>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)
>>>
>>>
>>>
>>
>>
>>
>
>
> --
> "http://ruby-lang.org -- do you ruby?"
>
> Jeff Wood
>
>
>
Jeff_Wood
(Jeff Wood)
17 October 2005 15:54
11
My mistake
I meant for the param to be sent to "each"
count = 0
xml.elements.each( "/a/d" ) { count += 1 }
puts count
j.
···
On 10/17/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
On 10/17/05, umitanuki <yasagure@umitanuki.net> wrote:
> 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.
> >
> > On 10/16/05, umitanuki <yasagure@umitanuki.net> wrote:
> >
> >>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)
> >>>
> >>>
> >>>
> >>
> >>
> >>
> >
> >
> > --
> > "http://ruby-lang.org -- do you ruby?"
> >
> > Jeff Wood
> >
> >
> >
>
>
>
>
My code was :
puts xml.elements['/a/d'].size
in previous post.
--
"http://ruby-lang.org -- do you ruby?"
Jeff Wood
umitanuki
(umitanuki)
17 October 2005 16:11
12
I didn't know such a code but it's seemed so useful.
Tanks,
umitanuki
Jeff Wood wrote:
···
My mistake
I meant for the param to be sent to "each"
count = 0
xml.elements.each( "/a/d" ) { count += 1 }
puts count
j.
On 10/17/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
On 10/17/05, umitanuki <yasagure@umitanuki.net> wrote:
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.
On 10/16/05, umitanuki <yasagure@umitanuki.net> wrote:
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)
--
"http://ruby-lang.org -- do you ruby?"
Jeff Wood
My code was :
puts xml.elements['/a/d'].size
in previous post.
--
"http://ruby-lang.org -- do you ruby?"
Jeff Wood