8

I have an XML file

<PARENT >
<TAG string1="asdf" string2="asdf" >
</TAG >
</PARENT>

I want to extract the string2 value here.. and also I want to set it to a new value..

How to do that?

Anandan
  • 983
  • 3
  • 13
  • 28

4 Answers4

17

Use XPath expressions

use strict;                                                                                                                      
use warnings;                                                                                                                    

use XML::LibXML;                                                                                                                 
use Data::Dumper;                                                                                                                

my $doc = XML::LibXML->new->parse_string(q{                                                                                      
<PARENT>                                                                                                                         
    <TAG string1="asdf" string2="asdfd">                                                                                         
    </TAG>                                                                                                                       
</PARENT>                                                                                                                        
});                                                                                                                              

my $xpath = '/PARENT/TAG/@string2';                                                                                              
# getting value of attribute:                                                                                                    
print Dumper $doc->findvalue($xpath);                                                                                            
my ($attr) = $doc->findnodes($xpath);                                                                                            

# setting new value:                                                                                                             
$attr->setValue('dfdsa');                                                                                                        
print Dumper $doc->findvalue($xpath);                                                                                            

# do following if you need to get string representation of your XML structure
print Dumper $doc->toString(1);                             

And read documentation, of course :)

zakovyrya
  • 9,579
  • 6
  • 39
  • 28
  • 2
    And of course, if you want to walk the DOM yourself, you can do that too. XML::LibXML uses the W3C DOM API, which is the same one you use in Javascript. So it should be readily familiar (although the API does suck, at least it's standard). – jrockway Aug 07 '09 at 04:26
  • 6
    @Anandan writing 'temme' instead of 'tell me' is not cool. In fact, it puts off some people such as myself who has to put in extra effort into mentally parsing what you are saying. The quality of answers you get in response to your questions is directly proportional to the effort you put into composing clear, well defined questions. – Sinan Ünür Aug 07 '09 at 14:34
  • @jrockway crappy DOM API can be relatively easy fixed by few thin wrappers that will make it more perlish. The biggest advantage of XML::LibXML over other admittedly more convenient modules is still its performance. Both speed and memory wise – zakovyrya Aug 08 '09 at 03:49
8

You could use XML::Parser to get the value as well. For more information refer to the XML::Parser documentation:

#!/usr/local/bin/perl
use strict;
use warnings;


use XML::Parser;
use Data::Dumper;

my $attributes = {};

my $start_handler = sub
{
    my ( $expat, $elem, %attr ) = @_;
    if ($elem eq 'TAG')
    {
        $attributes->{$attr{'string1'}} = 'Found';
    }
};


my $p1 = new XML::Parser(
        Handlers => {
            Start => $start_handler
        }
);

$p1->parsefile('test.xml');

print Dumper($attributes);
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
Logan
  • 276
  • 1
  • 5
2

I think you might be better off starting with XML::Simple and playing around a little first:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Simple;

my $xml = XMLin(\*DATA);

print $xml->{TAG}->{string2}, "\n";

$xml->{TAG}->{string2} = "asdf";

print XMLout( $xml, RootName => 'PARENT');

__DATA__
<PARENT>
<TAG string1="asdf" string2="value of string 2">
</TAG>
</PARENT>
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • 1
    Superficially looks simple, but xml::simple data strucutres eat memory for big documents, and the going gets really cryptic really quickly. – singingfish Aug 08 '09 at 02:18
  • @singingfish Take a look at the OP's post again. He does not know enough to be able to start learning the other libraries. He needs to *do* a little to learn *some* so that he can get to the stage where he knows what you mean in your comment. – Sinan Ünür Aug 08 '09 at 02:24
0

Thanks for your responses. I found another answer in "Config file processing with LibXML2" which I found very useful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anandan
  • 983
  • 3
  • 13
  • 28