Unit Testing with REXML questions

Discussion in 'Ruby' started by Peter Fitzgibbons, Oct 14, 2005.

  1. 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
     
    Peter Fitzgibbons, Oct 14, 2005
    #1
    1. Advertising

  2. Peter Fitzgibbons

    Jeff Wood Guest

    ------=_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.

    On 10/14/05, Peter Fitzgibbons <> 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

    ------=_Part_16167_15320578.1129291364849--
     
    Jeff Wood, Oct 14, 2005
    #2
    1. Advertising

  3. 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)
     
    Peter Fitzgibbons, Oct 14, 2005
    #3
  4. 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.
     
    Peter Fitzgibbons, Oct 14, 2005
    #4
  5. Peter Fitzgibbons

    umitanuki Guest

    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)
    >
    >
    >
     
    umitanuki, Oct 16, 2005
    #5
  6. Peter Fitzgibbons

    Jeff Wood Guest

    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.

    On 10/16/05, umitanuki <> 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 =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)
    > >
    > >
    > >

    >
    >
    >



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

    Jeff Wood
     
    Jeff Wood, Oct 16, 2005
    #6
  7. Peter Fitzgibbons

    umitanuki Guest

    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 <> 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, Oct 17, 2005
    #7
  8. On 10/17/05, umitanuki <> 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 =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.
    > >
    > > On 10/16/05, umitanuki <> 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 =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)
    > >>>
    > >>>
    > >>>
    > >>
    > >>
    > >>

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

    >
    >
    >
    >


    My code was :

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

    in previous post.
     
    Peter Fitzgibbons, Oct 17, 2005
    #8
  9. Peter Fitzgibbons

    Jeff Wood Guest

    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.

    On 10/17/05, Peter Fitzgibbons <> wrote:
    > On 10/17/05, umitanuki <> 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 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.
    > > >
    > > > On 10/16/05, umitanuki <> 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 =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)
    > > >>>
    > > >>>
    > > >>>
    > > >>
    > > >>
    > > >>
    > > >
    > > >
    > > > --
    > > > "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
     
    Jeff Wood, Oct 17, 2005
    #9
  10. Peter Fitzgibbons

    umitanuki Guest

    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 <> wrote:
    >
    >>On 10/17/05, umitanuki <> 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 <> 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, Oct 17, 2005
    #10
  11. On Oct 16, 2005, at 9:07 AM, Jeff Wood wrote:
    > 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.)
     
    Gavin Kistner, Oct 19, 2005
    #11
  12. Peter Fitzgibbons

    Jeff Wood Guest

    true.

    On 10/19/05, Gavin Kistner <> wrote:
    > On Oct 16, 2005, at 9:07 AM, Jeff Wood wrote:
    > > count =3D 0 ; xml.elements( '/a/d' ).each { count +=3D 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.)
    >
    >



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

    Jeff Wood
     
    Jeff Wood, Oct 19, 2005
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Maclean
    Replies:
    1
    Views:
    345
    Martin P. Hellwig
    Apr 13, 2010
  2. Ulrich Eckhardt

    unit-profiling, similar to unit-testing

    Ulrich Eckhardt, Nov 16, 2011, in forum: Python
    Replies:
    6
    Views:
    334
    Roy Smith
    Nov 18, 2011
  3. Bill Mosteller
    Replies:
    0
    Views:
    229
    Bill Mosteller
    Oct 22, 2009
  4. Avi
    Replies:
    0
    Views:
    496
  5. Avi
    Replies:
    0
    Views:
    464
Loading...

Share This Page