in reply to Re: XML::Twig - How do I check to see if an element exists in root?
in thread XML::Twig - How do I check to see if an element exists in root?

Joost, fantastic! Worked like a champ! Now I need to spend a few minutes to understand what the following line is doing.

twig_handlers => { map { $_ => sub { $found{$_->name()}++ }; } @nodes }
  • Comment on Re^2: XML::Twig - How do I check to see if an element exists in root?
  • Download Code

Replies are listed 'Best First'.
Re^3: XML::Twig - How do I check to see if an element exists in root?
by Joost (Canon) on Jul 05, 2007 at 10:39 UTC
    # specify twig_handlers (see the XML::Twig documentation) twig_handlers => { # create a new hash-ref map { # transform a list into a new list # create a name / subroutine pair $_ => sub { # when the subroutine is called # get the element name from $_->name() # and increase it's count entry in %found # # note: $_ is set by XML::Twig when the sub is called $found{$_->name()}++ }; } @nodes # for each element in @nodes }

    See also map.

      So I am assuming that the first $_ gets populated buy 'map' with the values from 'node'?

      What about the $_ in the hash found? Where does it get its value from?

      I searched for name() on the CPAN page for XML Parser and XML Twig and I could not find it? Where is the subroutine name() coming from.

      This code works but I am still abit confused on the mechanics of it.
        Sorry for the late reply.

        Anyway: map works by calling a codeblock for each element of the supplied list and passes the element as $_. (click the link to see the official docs for map)

        name() is mentioned on the XML::Twig documentation, in the (very long and not very well structured) section called METHODS. It just returns the "tag-name" for an XML::Elt, i.e. for <tagname attr="value" att2="value2"/> it returns the string "tagname".

        The code I supplied basically creates an anonymous subroutine, or code block, for each tag-name you're interested in and XML::Twig will call that subroutine whenever it finds a tag with that tag-name, passing an object (update: as $_ - which is generally considered poor style, but makes for short and possibly more readable code) that represents that tag (and you can call ->name() on that object to retrieve the tag name)