Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re^2: how to get attribute values and store in a hash.

by veerubiji (Sexton)
on Dec 13, 2011 at 16:02 UTC ( #943373=note: print w/replies, xml ) Need Help??

in reply to Re: how to get attribute values and store in a hash.
in thread how to get attribute values and store in a hash.

Hi, I am sorry for my mistakes. Thanks for your suggestion. I tried as you said but still problem is there, I am showing what I tried as below

#!/usr/bin/perl use warnings; use strict; use Carp; use File::Find; use File::Spec::Functions qw( canonpath ); use XML::LibXML::Reader; use Data::Dumper; my @ARGV ="c:/main/folder"; die "Need directories\n" unless @ARGV; my $Number; my %hash; find( sub { my $file = $_; # my $path = canonpath $File::Find::name; my $path =$_; return unless -f $path; return unless $file =~ /(_service\.xml)$/; extract_information($path, \%hash); return; }, @ARGV ); sub extract_information { my( $path, $hash)=@_; my $ret = open my $xmlin, '<', $path; unless ($ret) { carp "Cannot open '$path': $!"; return; } my $reader = XML::LibXML::Reader->new(IO => $xmlin); unless ($reader) { carp "Cannot create reader using '$path'"; return; } while ( $reader->nextElement( 'Service' )) { my $Number = $reader->getAttribute( 'num'); $reader->nextElement( 'Suppliermodules' ); while ( $reader->nextElement( 'Hardwaremodule' )) { my $module = {}; $module->{type} = $reader->getAttribute('Type'); $module->{nr} = $reader->getAttribute('Nr'); push @{$hash->{$Number}}, $module; } while ( $reader->nextElement( 'softwaremodule' )) { my $module1 = {}; $module1->{service} = $reader->getAttribute('Service'); push @{$hash->{$Number}}, $module1; } $reader->nextElement( 'customermodules' ); while ( $reader->nextElement( 'softwaremodule' )) { my $module2 = {}; $module2->{cusservice} = $reader->getAttribute('Service'); push @{$hash->{$Number}}, $module2; } } close $xmlin or carp "Cannot close '$path': $!"; return; } print Dumper \%hash;

I tried with find(\&wanted, @directories); to search directives But I have some difficulties with that so I fallowed my procedure.What I want to do is I need to create hash with service num as the key and and all information of software module and hardware module attributes in customer and supplier module elements are array of values for that key. here I have two elements customer and supplier modules so I think array of values in a hash value.So finally after running this script I need to look my hash like (Service num attribute as the key and remaining information as the array of values for that key. so I have all service nums as the keys and its information is array of values.) I tried like that in the above script but it doesn't give any errors.I am not getting exact output, it giving some element attributes and some service num's only.I am new to perl, I am not able to produce what I want, please help me with that. If any typing errors is there please excuse me.

My output like this

'B7a'=>[ { Service='ADC', path='....' } { Type='engine', Nr='18', Servicenum='1', path='....' } { Type='motor', Nr='7', Servicenum='1', path='....' } { Type='supply', Nr='1', Servicenum='1', path='....' } { Service='input', path='----' } { Service='signal', path='----' } ].....................

Thanks in advance.

Replies are listed 'Best First'.
Re^3: how to get attribute values and store in a hash.
by kennethk (Abbot) on Dec 14, 2011 at 19:35 UTC
    If you read How do I post a question effectively?, why are you still posting code that uses File::Find? I do not get your result because I do not have a c:/main/folder directory on my computer. Your issue is with parsing XML, so all your example should include is code to parse XML. You have almost 100 posts - seriously, you should know better by now. I've already given you a template for just working on your parsing logic.

    You have now provided an expected output, so I can modify my previous code to replicate your specified output, except of course that your quoted path's do not correspond to the paths in your XML and the order is different because your spec does not respect the order of the source document.

    #!/usr/bin/perl use warnings; use strict; use XML::LibXML::Reader; use Data::Dumper; my $hash_ref; my $reader = XML::LibXML::Reader->new( IO => *DATA ); while ( $reader->nextElement( 'Service' )) { my $number = $reader->getAttribute( 'Num'); $hash_ref->{$number} = []; $reader->read; while (1) { if ( $reader->localName eq 'Customermodules' or $reader->localName eq 'Suppliermodules') { $reader->read; while (1) { if ($reader->localName eq 'Softwaremodule') { my $module = {}; $module->{Service} = $reader->getAttribute('Servic +e'); $module->{path} = $reader->getAttribute('Path'); push @{$hash_ref->{$number}}, $module; } elsif ($reader->localName eq 'Hardwaremodule') { my $module = {}; $module->{Type} = $reader->getAttribute('Type'); $module->{Nr} = $reader->getAttribute('Nr'); $module->{Servicenum} = $reader->getAttribute('Ser +vicenum'); $module->{path} = $reader->getAttribute('Path'); push @{$hash_ref->{$number}}, $module; } $reader->nextSibling() > 0 or last; } } $reader->nextSibling() > 0 or last; } } $reader->finish; print Dumper $hash_ref; __DATA__ <?xml version="1.0" encoding="UTF-8"?> <Servicelist xmlns:xsi="" xsi +:noNamespaceSchemaLocation="file:///files/service.xsd"> <Service Num="B7a" Name="temperature sensor"> <Des>It delivers actual temperature in the form ov Volts</Des> <Customermodules> <Softwaremodule Service="ADC" Path="/main/ADCservice.xml"/> </Customermodules> <Suppliermodules> <Softwaremodule Service="input" Path="/main/inputservice.xml"/> <Softwaremodule Service="signal" Path="/main/signalservice.xml"/> <Hardwaremodule Type="engine" Nr="18" Servicenum="1" Path="/main/e +ngineservice.xml"/> <Hardwaremodule Type="motor" Nr="7" Servicenum="1" Path="/main/mo +torservice.xml"/> <Hardwaremodule Type="supply" Nr="1" Servicenum="1" Path="/main/sup +plyservice.xml"/> </Suppliermodules> </Service> </Servicelist>


    $VAR1 = { 'B7a' => [ { 'path' => '/main/ADCservice.xml', 'Service' => 'ADC' }, { 'path' => '/main/inputservice.xml', 'Service' => 'input' }, { 'path' => '/main/signalservice.xml', 'Service' => 'signal' }, { 'Type' => 'engine', 'Servicenum' => '1', 'path' => '/main/engineservice.xml', 'Nr' => '18' }, { 'Type' => 'motor', 'Servicenum' => '1', 'path' => '/main/motorservice.xml', 'Nr' => '7' }, { 'Type' => 'supply', 'Servicenum' => '1', 'path' => '/main/supplyservice.xml', 'Nr' => '1' } ] };

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://943373]
[LanX]: YM: talking about breaches ... did you read about Cambridge Analytica harvesting 50e6 FB profiles for political propaganda?
LanX ... oh ... Brexit delayed ... again ... oh wonder ...
[Your Mother]: Heh. I keeping seeing related headlines but my narcissism is a perihelion right now so I'm busy. :P
[LanX]: https://www. news/series/ cambridge- analytica-files
[Your Mother]: s/a /at /;
[LanX]: just watch the video ...
[Your Mother]: Roger, will co.

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2018-03-19 13:21 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (240 votes). Check out past polls.