FAQ
Hello, I am praticing below XML file.
Based on where I find att id for bayking id 'kingtony' , I wanted to
print out the entire element/att(and ID) and any text found from
<yahoo> to </yahoo>.(exception of bayqueen_list and its descendatns)...

I am having problem just print out one value... can someone take a look
please?

use strict;
use warnings;

use XML::Twig;

my $xml = <<XML;
<foo>
<yahoo V="bay">
<bay_id>
<value>1</value>
<fact>yes</fact>
</bay_id>
<bay_seen>
<value>10</value>
<fact>no</fact>
</bay_seen>
<bay_overall value="disabled"/>
<bayking_list>
<bayking id="kingjames" country="usa" active="true">
<bayking type="dictator"/>
<bay_usage value="none"/>
<bayking_origin>
<bayking_origin_name value="ohio_usa"
emmigrate="no">
<economy_status_previous value="very poor" />
</bayking_origin_name>
</bayking_origin>
</bayking>
</bayking_list>
<bayqueen_list>
<bayqueen id="queenliz" country="france" active="true">
<bayqueen type="dictator"/>
<bay_usage value="none"/>
<bayqueen_origin>
<bayqueen_origin_name value="ohio_usa"
emmigrate="no"/>
</bayqueen_origin>
</bayqueen>
</bayqueen_list>
</yahoo>
<yahoo V="baz">
<bay_id>
<value>1000</value>
<fact>yes</fact>
</bay_id>
<bay_seen>
<value>50</value>
<fact>no</fact>
</bay_seen>
<bay_overall value="disabled"/>
<bayking_list>
<bayking id="kingtony" country="Russia" active="true">
<bayking type="dictator"/>
<bay_usage value="none"/>
<bayking_origin>
<bayking_origin_name value="ohio_usa"
emmigrate="no">
<economy_status_previous value="very poor" />
</bayking_origin_name>
</bayking_origin>
</bayking>
</bayking_list>
<bayqueen_list>
<bayqueen id="queensarah" country="japan" active="true">
<bayqueen type="dictator"/>
<bay_usage value="none"/>
<bayqueen_origin>
<bayqueen_origin_name value="ca_usa"
emmigrate="no"/>
<economy_status_previous value="very poor" />
<previous marriage="no"/>
</bayqueen_origin>
</bayqueen>
</bayqueen_list>
</yahoo>
</foo>
XML

my $t = XML::Twig->new
(
twig_handlers => { '/foo/yahoo/bayking_list' => sub
{
my @bay = $_->children('bayking');
foreach my $bay1 ( @bay ) {
if ( $bay1->att('id' eq 'kingtony' ) ) {
# print all elements/att/value and text from <yahoo> to
</yahoo> which contains kingtony but do NOT print out bayqueen
print $bay1->att('id') . "\n";
}
}
}
}
);

$t->parse ($xml);

Search Discussions

  • Richard Lee at Nov 16, 2008 at 2:40 am
    use strict;
    use warnings;

    use XML::Twig;

    my $xml = <<XML;
    <foo>
    <yahoo V="bay">
    <bay_id>
    <value>1</value>
    <fact>yes</fact>
    </bay_id>
    <bay_seen>
    <value>10</value>
    <fact>no</fact>
    </bay_seen>
    <bay_overall value="disabled"/>
    <bayking_list>
    <bayking id="kingjames" country="usa" active="true">
    <bayking type="dictator"/>
    <bay_usage value="none"/>
    <bayking_origin>
    <bayking_origin_name value="ohio_usa"
    emmigrate="no">
    <economy_status_previous value="very poor" />
    </bayking_origin_name>
    </bayking_origin>
    </bayking>
    </bayking_list>
    <bayqueen_list>
    <bayqueen id="queenliz" country="france" active="true">
    <bayqueen type="dictator"/>
    <bay_usage value="none"/>
    <bayqueen_origin>
    <bayqueen_origin_name value="ohio_usa"
    emmigrate="no"/>
    </bayqueen_origin>
    </bayqueen>
    </bayqueen_list>
    </yahoo>
    <yahoo V="baz">
    <bay_id>
    <value>1000</value>
    <fact>yes</fact>
    </bay_id>
    <bay_seen>
    <value>50</value>
    <fact>no</fact>
    </bay_seen>
    <bay_overall value="disabled"/>
    <bayking_list>
    <bayking id="kingtony" country="Russia" active="true">
    <bayking type="dictator"/>
    <bay_usage value="none"/>
    <bayking_origin>
    <bayking_origin_name value="ohio_usa"
    emmigrate="no">
    <economy_status_previous value="very poor" />
    </bayking_origin_name>
    </bayking_origin>
    </bayking>
    </bayking_list>
    <bayqueen_list>
    <bayqueen id="queensarah" country="japan" active="true">
    <bayqueen type="dictator"/>
    <bay_usage value="none"/>
    <bayqueen_origin>
    <bayqueen_origin_name value="ca_usa"
    emmigrate="no"/>
    <economy_status_previous value="very poor" />
    <previous marriage="no"/>
    </bayqueen_origin>
    </bayqueen>
    </bayqueen_list>
    </yahoo>
    </foo>
    XML

    my $sabal = new XML::Twig(
    twig_roots => {
    'bayking[@id="kingtony"]' =>
    sub {
    my ($yabal, $element ) = @_;
    $element->print;
    }
    }
    );

    above produces,

    <bayking active="true" country="Russia" id="kingtony"><bayking
    type="dictator"/><bay_usage
    value="none"/><bayking_origin><bayking_origin_name emmigrate="no"
    value="ohio_usa"><economy_status_previous value="very
    poor"/></bayking_origin_name></bayking_origin></bayking>

    which is very close to what i need but I really need it to traverse all
    the way top to <yahoo> and traverse down back all the way to </yahoo>..

    I thought sub'ing $element->print to //../../$element->print would work
    but does not....
  • Chas. Owens at Nov 16, 2008 at 3:24 am
    On Sat, Nov 15, 2008 at 16:27, Richard Lee wrote:
    snip
    if ( $bay1->att('id' eq 'kingtony' ) ) {
    snip

    I think you mean to say

    if ($bay1->att("id") eq "kingtony") {

    --
    Chas. Owens
    wonkden.net
    The most important skill a programmer can have is the ability to read.
  • Richard Lee at Nov 16, 2008 at 4:06 am

    Chas. Owens wrote:
    On Sat, Nov 15, 2008 at 16:27, Richard Lee wrote:
    snip
    if ( $bay1->att('id' eq 'kingtony' ) ) {
    snip

    I think you mean to say

    if ($bay1->att("id") eq "kingtony") {
    yes, that was a typo...
  • Richard Lee at Nov 16, 2008 at 4:18 am

    Richard Lee wrote:
    Chas. Owens wrote:
    On Sat, Nov 15, 2008 at 16:27, Richard Lee wrote:
    snip
    if ( $bay1->att('id' eq 'kingtony' ) ) {
    snip

    I think you mean to say

    if ($bay1->att("id") eq "kingtony") {
    yes, that was a typo...
    I changed to

    my $sabal = new XML::Twig(
    twig_roots => {
    'foo/yahoo' =>
    #'bayking[@id="kingtony"]' =>
    sub {
    my ($yabal, $element ) = @_;
    if (
    $yabal->first_child('bayking_list')->first_child('bayking')->att('id')
    eq 'kingtony' ) {
    $element->print;
    }
    }
    }
    );

    $sabal->parse($xml);

    but still no luck..
  • Chas. Owens at Nov 16, 2008 at 4:20 am

    On Sat, Nov 15, 2008 at 23:18, Richard Lee wrote:
    Richard Lee wrote:
    Chas. Owens wrote:
    On Sat, Nov 15, 2008 at 16:27, Richard Lee wrote:
    snip
    if ( $bay1->att('id' eq 'kingtony' ) ) {
    snip

    I think you mean to say

    if ($bay1->att("id") eq "kingtony") {
    yes, that was a typo...
    I changed to

    my $sabal = new XML::Twig(
    twig_roots => {
    'foo/yahoo' =>
    #'bayking[@id="kingtony"]' =>
    sub {
    my ($yabal, $element ) = @_;
    if (
    $yabal->first_child('bayking_list')->first_child('bayking')->att('id') eq
    'kingtony' ) {
    $element->print;
    }
    }
    }
    );

    $sabal->parse($xml);

    but still no luck..

    Perhaps I am dense, but what is the desired output from the given XML?

    --
    Chas. Owens
    wonkden.net
    The most important skill a programmer can have is the ability to read.
  • Richard Lee at Nov 16, 2008 at 4:27 am

    Chas. Owens wrote:


    Perhaps I am dense, but what is the desired output from the given XML?
    Hello Chas,

    From xml file, based on attribute value for bayking id, I want to find
    kingtony and then I want to traverse back up to yahoo and print
    everything from
    <yahoo> to </yahoo>

    I have tried to use xpath //../../bayking but doesn't seem to work.

    I am trying to ultimately push below find value into hash of hash
    reference such as

    <yahoo V="baz"> $list{'yahoo'} = { 'V' => 'baz'}

    <bayking id="kingtony" country="Russia" active="true">
    $list{'bayking'} = { 'id' => 'kingtony' , 'country' => 'Russia',
    'active' => 'true' }

    I am able to find what I am looking for 'kingtony' but having tough time
    traversing back to right yahoo element and accessing all data.


    <yahoo V="baz">
    <bay_id>
    <value>1000</value>
    <fact>yes</fact>
    </bay_id>
    <bay_seen>
    <value>50</value>
    <fact>no</fact>
    </bay_seen>
    <bay_overall value="disabled"/>
    <bayking_list>
    <bayking id="kingtony" country="Russia" active="true">
    <bayking type="dictator"/>
    <bay_usage value="none"/>
    <bayking_origin>
    <bayking_origin_name value="ohio_usa"
    emmigrate="no">
    <economy_status_previous value="very poor" />
    </bayking_origin_name>
    </bayking_origin>
    </bayking>
    </bayking_list>
  • Richard Lee at Nov 16, 2008 at 4:40 am

    Richard Lee wrote:
    Chas. Owens wrote:
    my $sabal = new XML::Twig(
    twig_roots => {
    'foo/yahoo' =>
    #'bayking[@id="kingtony"]' =>
    sub {
    my ($yabal, $element ) = @_;
    if (
    $element->first_child('bayking_list')->first_child('bayking')->att('id')
    eq 'kingtony' ) {
    $element->print;
    }
    }
    }
    );

    I think I made a mistake .. this is now working...

    <yahoo
    V="baz"><bay_id><value>1000</value><fact>yes</fact></bay_id><bay_seen><value>50</value><fact>no</fact></bay_seen><bay_overall
    value="disabled"/><bayking_list><bayking active="true" country="Russia"
    id="kingtony"><bayking type="dictator"/><bay_usage
    value="none"/><bayking_origin><bayking_origin_name emmigrate="no"
    value="ohio_usa"><economy_status_previous value="very
    poor"/></bayking_origin_name></bayking_origin></bayking></bayking_list><bayqueen_list><bayqueen
    active="true" country="japan" id="queensarah"><bayqueen
    type="dictator"/><bay_usage
    value="none"/><bayqueen_origin><bayqueen_origin_name emmigrate="no"
    value="ca_usa"/><economy_status_previous value="very poor"/><previous
    marriage="no"/></bayqueen_origin></bayqueen></bayqueen_list></yahoo>

    Now, I just need good way to put this into hash of hash referernce.....
  • Richard Lee at Nov 16, 2008 at 8:26 am

    Richard Lee wrote:
    Richard Lee wrote:
    Chas. Owens wrote:
    my $sabal = new XML::Twig(
    twig_roots => {
    'foo/yahoo' =>
    #'bayking[@id="kingtony"]' =>
    sub {
    my ($yabal, $element ) = @_;
    if (
    $element->first_child('bayking_list')->first_child('bayking')->att('id')
    eq 'kingtony' ) {
    $element->print;
    }
    }
    }
    );

    I think I made a mistake .. this is now working...

    <yahoo
    V="baz"><bay_id><value>1000</value><fact>yes</fact></bay_id><bay_seen><value>50</value><fact>no</fact></bay_seen><bay_overall
    value="disabled"/><bayking_list><bayking active="true"
    country="Russia" id="kingtony"><bayking type="dictator"/><bay_usage
    value="none"/><bayking_origin><bayking_origin_name emmigrate="no"
    value="ohio_usa"><economy_status_previous value="very
    poor"/></bayking_origin_name></bayking_origin></bayking></bayking_list><bayqueen_list><bayqueen
    active="true" country="japan" id="queensarah"><bayqueen
    type="dictator"/><bay_usage
    value="none"/><bayqueen_origin><bayqueen_origin_name emmigrate="no"
    value="ca_usa"/><economy_status_previous value="very poor"/><previous
    marriage="no"/></bayqueen_origin></bayqueen></bayqueen_list></yahoo>

    Now, I just need good way to put this into hash of hash referernce.....
    ok so I gave up putting them into has of hash reference because of
    unpredictableness of items..
    I can get to all values by doing manual $_->first_child method... but my
    problem is, I don't know how to extract all information on
    <yahoo V="baz">..... how do I get that? $_->parent?
  • Richard Lee at Nov 16, 2008 at 4:20 pm

    Richard Lee wrote:

    I think I made a mistake .. this is now working...

    <yahoo
    V="baz"><bay_id><value>1000</value><fact>yes</fact></bay_id><bay_seen><value>50</value><fact>no</fact></bay_seen><bay_overall
    value="disabled"/><bayking_list><bayking active="true"
    country="Russia" id="kingtony"><bayking type="dictator"/><bay_usage
    value="none"/><bayking_origin><bayking_origin_name emmigrate="no"
    value="ohio_usa"><economy_status_previous value="very
    poor"/></bayking_origin_name></bayking_origin></bayking></bayking_list><bayqueen_list><bayqueen
    active="true" country="japan" id="queensarah"><bayqueen
    type="dictator"/><bay_usage
    value="none"/><bayqueen_origin><bayqueen_origin_name emmigrate="no"
    value="ca_usa"/><economy_status_previous value="very poor"/><previous
    marriage="no"/></bayqueen_origin></bayqueen></bayqueen_list></yahoo>

    Now, I just need good way to put this into hash of hash referernce.....
    ok so I gave up putting them into has of hash reference because of
    unpredictableness of items..
    I can get to all values by doing manual $_->first_child method... but
    my problem is, I don't know how to extract all information on
    <yahoo V="baz">..... how do I get that? $_->parent?
    After I extracted above xml, what is the proper way to loop through them
    and extract all information?
    I like my final output to look like,

    yahoo V: baz
    bay_id value: 1000 fact: yes
    bay_seen value: 50 fact: no
    ...... and so on....
  • Rob Dixon at Nov 19, 2008 at 3:38 pm

    Richard Lee wrote:
    Richard Lee wrote:
    I think I made a mistake .. this is now working...

    <yahoo
    V="baz"><bay_id><value>1000</value><fact>yes</fact></bay_id><bay_seen><value>50</value><fact>no</fact></bay_seen><bay_overall
    value="disabled"/><bayking_list><bayking active="true"
    country="Russia" id="kingtony"><bayking type="dictator"/><bay_usage
    value="none"/><bayking_origin><bayking_origin_name emmigrate="no"
    value="ohio_usa"><economy_status_previous value="very
    poor"/></bayking_origin_name></bayking_origin></bayking></bayking_list><bayqueen_list><bayqueen
    active="true" country="japan" id="queensarah"><bayqueen
    type="dictator"/><bay_usage
    value="none"/><bayqueen_origin><bayqueen_origin_name emmigrate="no"
    value="ca_usa"/><economy_status_previous value="very poor"/><previous
    marriage="no"/></bayqueen_origin></bayqueen></bayqueen_list></yahoo>

    Now, I just need good way to put this into hash of hash referernce.....
    ok so I gave up putting them into has of hash reference because of
    unpredictableness of items..
    I can get to all values by doing manual $_->first_child method... but
    my problem is, I don't know how to extract all information on
    <yahoo V="baz">..... how do I get that? $_->parent?
    After I extracted above xml, what is the proper way to loop through them
    and extract all information?
    I like my final output to look like,

    yahoo V: baz
    bay_id value: 1000 fact: yes
    bay_seen value: 50 fact: no
    ...... and so on....
    This code may help you.

    my $t = XML::Twig->new(
    twig_handlers => {
    '/foo/yahoo' => sub {

    printf "%s %s:%s\n", $_->tag, 'V', $_->att('V');

    foreach my $elem ($_->children) {

    next if $elem->tag eq 'bayqueen_list';

    print $elem->tag;
    foreach my $subelem ($elem->children) {
    printf " %s: %s", $subelem->tag, $subelem->text;
    }
    print "\n";
    }
    }
    }
    );


    But you need to decide what you are trying to do. A generalized program to dump
    all the text and attribute values from an arbitrary piece of XML data has to be
    recursive and is probably not what you want.

    First you talked about putting the data into a hash, and now you say you want to
    print it. What is your ultimate goal?

    HTH,

    Rob

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedNov 15, '08 at 9:27p
activeNov 19, '08 at 3:38p
posts11
users3
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase