Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problem with xml::parser 1

Status
Not open for further replies.

donny750

Programmer
Jul 13, 2006
145
FR
Hello,

I've search in the perl forum the script who talk about xml::parser and i've found one interesting :
[URL unfurl="true"]http://www.tek-tips.com/viewthread.cfm?qid=1161992
[/url]

i've taken the script and modify it for my xml file
Code:
#!/usr/bin/perl -w

use strict;
use XML::Parser;

my $parser = XML::Parser->new( Handlers => {
        Start =>    \&handle_elem_start,
                                             });
my $file = 'instance.xml';
$parser->parsefile($file);

sub handle_elem_start {
    my ($expat, $name, %atts) = @_;
    if ( uc($name) eq 'information') {
        print uc($name), " found - type : $atts{'type'}\n";
    }
}

my xml file
<?xml version="1.0" encoding="windows-1250"?>
<root value="x">
<entreprise>some text</entreprise>
<info></info>
<client>
<nom name="paul">
<information valeur="Niveau" type="Bon"/>
<information valeur="Solvable" type="Mauvais"/>
</nom>
</client>
<client>
<nom name="albine">
<information valeur="Solvable" type="Bon"/>
</nom>
</client>
<client>
<nom name="Terence">
<information valeur="Niveau" type="Tres bon"/>
<information valeur="Solvable" type="Bon"/>
<information valeur="Ancien" type="Oui"/>
</nom>
</client>
</root>

when i launch the script i've nothing ???
normally i must have this result
information found - type : Bon
information found - type : Mauvais
information found - type : Bon
information found - type : Tres bon
information found - type : Bon
information found - type : Oui


why i've not this ???


thanks
 
from what I can tell your tag is lowercase but you are looking for uppercase..
Code:
if ( uc($name) eq 'information')

uc($name) means to uppercase the content of $name so it now holds INFORMATION and you then check to see if it equals 'information'.

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
i've modify the script

Code:
sub handle_elem_start {
    my ($expat, $name, %atts) = @_;
    if ( $name eq 'information') {
    if ($atts{'valeur'} eq 'Niveau') {
        print uc($name), " found - type : $atts{'type'}\n";
        }
    }
}

for take only the tag with the attribute valeur equal to Niveau
and it 's possible to print the the value of the attribute name in the tag nom
to obtains this
For CLIENT name : paul
INFORMATION found - type : Bon
For CLIENT name : Terrence
INFORMATION found - type : Tres bon
 
what output do you get with your code change

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
try this ...
Code:
sub handle_elem_start {
    my ($expat, $name, %atts) = @_;
    if ( $name eq 'nom' ) {
                print "CLIENT : $atts{'name'}\n";
    }
    if ( $name eq 'information') {
    if ($atts{'valeur'} eq 'Niveau') {
        print uc($name), " found - type : $atts{'type'}\n";
        }
    }
}

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
thanks;

i've made this

Code:
my $x;
sub handle_elem_start {
    my ($expat, $name, %atts) = @_;
    
    if ( $name eq 'nom') {
    $x = $atts{'name'};
    }
    if ( $name eq 'information') {
    
    if ($atts{'valeur'} eq 'Niveau') 
        {
        print $x."\n";
        print uc($name), " found - type : $atts{'type'}\n";
        }
    
    }

}

because if i make like you
i've the name of the people who haven't a "Niveau
 
good call ;-)

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I have another sub;
Her name is
sub handle_elem_suite


I've made this for call her
Code:
#!/usr/bin/perl -w

use strict;
use XML::Parser;

my $parser = XML::Parser->new( Handlers => {
        Start =>    \&handle_elem_start,&handle_elem_suite,
                                             });


but it's not run
why ???
it's impossible to call 2 fonctions ??
 
try checking out the CPAN documentation on the module..
also if it does handle them you would need to put a slash infront of it...
Code:
my $parser = XML::Parser->new( Handlers => {
        Start =>    \&handle_elem_start, \&handle_elem_suite,
                                             });

there are multiple handlers
Start => \&handle_start,
End => \&handle_end,
and it seems they are separated by commas so i'm not sure your syntax will work...

I don't know if you could simply use spaces for each function?
Code:
Start => \&handle_start \&another_sub



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Or you could call your second sub (&handle_elem_suite) from the event handler sub (&handle_elem_start). Something like the following:
Code:
sub handle_elem_start {
    # Element Start Code
    .
    .
    .
    handle_elem_suite( @args );
}
 
thanks you for your help;

I've just one question;
Think you is posible with the perl xml parser, to modify something in the xml file;

for example i've this
<client>
<nom name="paul">
<information valeur="Niveau" type="Bon"/>
<information valeur="Solvable" type="Mauvais"/>
</nom>
</client>
and i will parse my xml file to modify the value of the attribute "type" and obtain this

<client>
<nom name="paul">
<information valeur="Niveau" type="Mauvais"/>
<information valeur="Solvable" type="Mauvais"/>
</nom>
</client>

it's possible with a parser for you , or it's a dream ?
 
for doing this i've know i must use Xpath for find the value of the attribute, i've want to modify
i've this script

Code:
#!/usr/bin/perl -w

use strict;
use XML::XPath;
use XML::XPath::XMLParser;
use XML::Twig;

# create an object to parse the file and field XPath queries
# my $xpath = XML::XPath->new( filename => shift @ARGV );
my $xpath = XML::XPath->new( filename => "client.xml" );

# apply the path from the command line and get back a list matches
my $field;
my @field = "string";

my $old_value = $xpath->find("//nom[\@name='pivot']/information[\@type]/text()" );

print $old_value."\n";

my xml file

<?xml version="1.0" encoding="windows-1250"?>
<root value="x">
<entreprise>some text</entreprise>
<info></info>
<client>
<nom name="pivot">
<information valeur="Niveau" type="Bon">xxx</information>
</nom>

<nom name="paul">
<information valeur="Niveau" type="Bon">xxx</information>
<information valeur="Solvable" type="Mauvais">zoooooooo</information>
</nom>
</client>
<client>
<nom name="albine">
<information valeur="Solvable" type="Bon">azer</information>
</nom>
</client>
<client>
<nom name="Terence">
<information valeur="Niveau" type="Tres bon"/>
<information valeur="Solvable" type="Bon"/>
<information valeur="Ancien" type="Oui"/>
</nom>
</client>
</root>

when i run the script i've this result
"xxx" instead of having "Bon"

???

 
i've found
i must this
Code:
my $old_value = $xpath->find("//nom[\@name='pivot']/information/\@type" );
 
nice one, have a star!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top