gr.d has asked for the wisdom of the Perl Monks concerning the following question:

How do you extract the values/attributes from all the XML tags using Perl and output them once Example XML

<Root> <tags> <first name="AA"> <A1 name="A"/> <B1 name="B"/> </first> <second name="BB"> <A1 name="A"/> <B1 name="B"/> <C1 name="C"/> </second> <Third name="CC"> <A1 name="A"/> <B1 name="B"/> <C1 name="C/> </Third> <Fourth name="DD"> <A1 name="A"/> <B1 name="B/> <C1 name="C/> </Fourth> </tags> <Root>

Output: I just need the output which is:

A B C
Any help is appreciated Note:I'm using XML::Simple, I know XML::Simple is not that easy. Kindly do post a example code just for reference. Because I'm unclear where to start

Original node content restored above by GrandFather

how to declare wires for verilog using perl. The XML data has the following information for modules which is needed Example XML

<Root> <tags> <Module ="AA"> <Input name="cpu_control"/> <Output name="power_control"/> </first> <module="BB"> <Input name="data_b"/> <output name="data_out"/> <bidirection name="add_bus"/> </second> <Module="CC"> <Input name="power_con"/> <Bidirection name="data_b"/> </Third> </tags> </Root>

I'm trying to generate a wire declaration for verilog using perl scripting. I however have an idea on how to do it, but less clue on implementing it. The Idea I have is, "foreach lower module the signals of inputs, outputs, inouts(bidirection) if not present in the top module then these should be declared as wires."

sample output: wire power_control; wire add_bus; wire cpu_control;
My code use warnings; use XML::Simple; use Data::Dumper; my $xml=XMLin('sample.xml'); my $roottags=$xml->{tags}; my $topmodule=$roottags->{Module}; my @mod=keys %$topmodule; foreach my $modules(values %$topmodule) { my $modu_temp=shift(@mod); #print "$modu_temp\n"; #my $ins_mod=$modules->{input}; my @ins=(keys %{$modules->{input}}); if(exists $ins[0]){} else{ $in_1=$modules->{input}; @ins=$in_1->{name}; } print @ins, "\n"; }

Is my logic close enough? because I get the output which I dont want

Any help is appreciated Note:I'm using XML::Simple, I know XML::Simple is not that easy. Kindly do post a example code just for reference. Because I'm unclear where to start

Replies are listed 'Best First'.
Re: Extract attributes/values from XML using perl
by choroba (Cardinal) on Jan 07, 2016 at 13:08 UTC
    The XML is not well formed. In the Fourth element, B and C are missing the closing double quotes, and Root's closing tag needs a slash. Your specification conflicts with the output: why are AA, BB, CC, and DD not printed?

    In xsh, you'd just hash the attributes:

    open file.xml ; $h := hash . //@* ; echo { join "\n", keys $h } ;

    Similarly, in XML::LibXML:

    #! /usr/bin/perl use warnings; use strict; use XML::LibXML; my $xml = 'XML::LibXML'->load_xml( location => 'file.xml' ); my %h; for ($xml->findnodes('//@*')) { $h{ $_->value } = 1; } print "$_\n" for keys %h;

    If you only want attributes of elements with no subelements, change the XPath expression to

    //*[not(./*)]/@*

    Update: Not so simple in XML::Simple:

    #! /usr/bin/perl use warnings; use strict; use feature qw{ say }; use XML::Simple; my $xml = XMLin('file.xml', ForceArray => 1, KeyAttr => [], ForceContent => 1); my %h; @h{ map values %{ $_->[0] }, grep 'ARRAY' eq ref, map values %{ $_->[0] }, values %{ $xml->{tags}[0] } } = (); say for keys %h;
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      the AA BB CC are just examples, not really concentrating on that now

      I'm currently using the perl version 5.8.8 and "feature" is in perl 5.10 if I'm not wrong. Anyway to surpass this hurdle?. Since the upgrade is in the admins hand and that is not happening anytime soon, was hoping something can be done

        It's not relevant to the problem. Use print instead of say and add a newline.
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Agree with choroba's post that you don't need the feature 'say' to solve your issue. But FYI, in Perl you can create your own global functions with the core module Exporter. A very naive implementation:

        In MyFeatures.pm:

        package MyFeatures; use strict; use warnings; use Exporter qw/ import /; our @EXPORT_OK = qw/ say /; sub say { my $str = shift; print "$str\n"; } 1; # return true

        In your program:

        #!/usr/bin/perl use strict; use warnings; use MyFeatures qw/ say /; my $str = 'Hello, world.'; say $str; say q{Nice weather, isn't it?}; __END__

        Output:

        Hello, world. Nice weather, isn't it?

        Hope this helps.

        The way forward always starts with a minimal test.

      a minor update on my post, any thoughts on how to do this?

      thanks!

        a minor update on my post, any thoughts on how to do this?

        :) its minor, you handle it using provided code as example

      Corrected

      how can this be done with XML::Simple?

Re: Extract attributes/values from XML using perl
by Discipulus (Canon) on Jan 07, 2016 at 12:38 UTC
    I know XML::Simple is not that easy...

    No, his problem is not easyness but rightness: See XML::Simple needs to go!

    I'd prefere XML::Twig that has also good tutorials on his own website, with fully explained basic (and advanced) examples.

    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Extract attributes/values from XML using perl
by Corion (Patriarch) on Jan 07, 2016 at 12:20 UTC

    What code do you have and where do you have problems?

    How would you do it, if you were to do it manually?

    Also see perlfaq4 on "unique".

      @corion: Thank you for your time!