Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

map <IF> to hash with replacement

by vit (Pilgrim)
on Feb 04, 2010 at 23:37 UTC ( #821475=perlquestion: print w/ replies, xml ) Need Help??
vit has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
I have an XML file which I want to convert to hash removing tags. It is not a problem, but I want to do it nice with one map {}
This works
my %hash = map { lc($_), 1 } <IF>;
but I need something like that
%hash = map { lc($_), 1; s/<tag>//; s/<\/tag>// } <IF>;
which does not work.

Comment on map <IF> to hash with replacement
Select or Download Code
Re: map <IF> to hash with replacement
by almut (Canon) on Feb 04, 2010 at 23:52 UTC
    %hash = map { $_=lc($_); s/<tag>//; s/<\/tag>//; $_ => 1 } <IF>;
      So in map we go from left to right ?

        Yes.  Just like you normally go from top to bottom when the statements are written on separate lines:

        { $_=lc($_); s/<tag>//; s/<\/tag>//; $_ => 1 }

        Yes, just like in a program we go from top to bottom.

        map 'returns' a result for each element processed. The result is the last value of the last statement in the map block and may be a list. Consider:

        #!/usr/bin/perl use strict; use warnings; my @lines = qw(<tag>A</tag> <TAG>B</TAG> <tag>C</tag>); for my $expr ( 'lc', 'lc($_), 1', '$_=lc($_); s/<tag>//; s/<\/tag>//; $_ => 2' ) { my @values = eval "map {$expr} \@lines"; print join("\n ", "map {$expr} =>", @values), "\n"; }


        map {lc} => <tag>a</tag> <tag>b</tag> <tag>c</tag> map {lc($_), 1} => <tag>a</tag> 1 <tag>b</tag> 1 <tag>c</tag> 1 map {$_=lc($_); s/<tag>//; s/<\/tag>//; $_ => 2} => a 2 b 2 c 2

        That result can be a list (as shown by almut

        True laziness is hard work

        Statements are always executed from the earliest in the file to the latest in the file (unless overridden by loops, etc, of course). The statements in a map block are no exception.

Re: map <IF> to hash with replacement
by crashtest (Curate) on Feb 05, 2010 at 01:49 UTC

    Your immediate problem seems to be solved, but based on your question, I am guessing you are doing some sort of XML processing. If you are, I'd suggest you skip re-inventing any wheels and consider the resources already available.

    The main XML parsing module on CPAN is XML::Parser. A handier interface to it is provided by XML::Simple.

    PerlMonks has a tutorial on XML::Parser, although it's almost ten years old.

    Edit: As I wrote this, in the back of my mind I was hoping that another monk would help out in case my recommendations were out of date. Your Mother came through - thanks!

      I understand this is well intentioned but I think it's bad advice. XML::Twig, XML::Rules, and XML::LibXML are probably all to be preferred over XML::Parser; I'd argue the libxml wrapper is definitely a better choice. And XML::Simple is anything but; it's a maze of special cases and their mapping parameters. It can be a very useful module but I wouldn't recommend it without knowing the problem and input at hand.

        I would use XML::Simple. It's dead easy to bring XML in as Perl structures.
        use XML::Simple qw{XMLin}; print keys %{XMLin("<root><x>1</x><y>2</y></root>")};
        This prints "xy".

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://821475]
Approved by planetscape
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2014-10-20 23:33 GMT
Find Nodes?
    Voting Booth?

    For retirement, I am banking on:

    Results (93 votes), past polls