amitp2011 has asked for the wisdom of the Perl Monks concerning the following question:

I have to update the value of a node by based on the value of one of its attributes.

<ReferenceID referenceIDType="FXDD">FXDDILN233</ReferenceID> For the above Tag. i want to edit the value FXDDILN233 based on the attribute value referenceIDType="FXDD"

I tried the below code:
my $nodeset = $doc->findnodes("//*[name()='ReferenceID']"); foreach my $node ($nodeset->get_nodelist) { if ($node->hasAttribute("referenceIDType") == XML::LibXML::Boolean- +>True) { $RetVal = $node->getAttributeNode("referenceIDType")->getValue(); if ($RetVal eq "FDD") { print "Attribute VAL=@@@@@@@@@@@@"."$RetVal \n"; $node->setData("$NodeVal"); } } }
But getting error on the setData line.. Whats is it that could be wrong ? Thanks in advance.

Replies are listed 'Best First'.
Re: Update an XML node value based on one of the attribute values.
by tobyink (Canon) on Apr 18, 2014 at 07:55 UTC

    XML::LibXML::Element doesn't have a setData method. XML::LibXML::Text, XML::LibXML::Comment, and XML::LibXML::PI do. I think perhaps you want:

    $node->firstChild->setData("blahblah");

    Here's a demo:

    use strict; use warnings; use XML::LibXML 2; my $doc = 'XML::LibXML'->load_xml(IO => \*DATA); foreach my $node ( $doc->findnodes('//ReferenceID') ) { $node->firstChild->setData("Reference ID type is $node->{reference +IDType}") if $node->{referenceIDType} eq 'FXDD'; } print $doc->toString; __DATA__ <root> <ReferenceID referenceIDType="FXDD">FXDDILN233</ReferenceID> </root>
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      But where are we setting the value of node ReferenceID.

        amitp2011:

        He's not setting it--tobyink was simply showing you how to get the desired element that has the setData method. Frequently, when answering questions, we show you how to get past the stumbling point, we figure you can take it from there. ;^)

        By the way, if you would, please edit your first post in this thread and remove the blank from the closing </Code> tag.change the code tags from <Code> to <code>, so the code displays correctly. (Don't forget to change the closing tag, too!)

        Update: ambrus pointed out that the problem in the original post was that the problem wasn't the case, but that there was an extra blank in the closing tag.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

      Thanks.. my issue resolved.

      $node->firstChild->setData("blahblah");

      did the trick :)
Re: Update an XML node value based on one of the attribute values.
by Anonymous Monk on Apr 18, 2014 at 06:44 UTC

    But getting error on the setData line.. Whats is it that could be wrong ? Thanks in advance.

    What is this error? copy/paste friend :)

      Can't locate object method "setdata" via package "XML::LibXML::Element" at FX_Booking.pl line 460. This is the error i got.
        Well neither XML::LibXML::Element nor its base class XML::LibXML::Node list any "setdata" method, so not sure why you keep trying to use it :)

        $ perl -MXML::LibXML -le " print XML::LibXML::Element->new" Usage: XML::LibXML::Element::new(CLASS, name) at -e line 1. $ perl -MXML::LibXML -le " print XML::LibXML::Element->new(q{q})" <q/> $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +setData; print $q;" Can't locate object method "setData" via package "XML::LibXML::Element +" at -e line 1. $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +setValue; print $q;" Can't locate object method "setValue" via package "XML::LibXML::Elemen +t" at -e line 1. $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +nodeValue(66); print $q;" <q/> $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +nodeValue=(66); print $q;" Modification of a read-only value attempted at -e line 1. $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +replaceValue(55); print $q;" Can't locate object method "replaceValue" via package "XML::LibXML::El +ement" at -e line 1. $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +replaceText(55); print $q;" Can't locate object method "replaceText" via package "XML::LibXML::Ele +ment" at -e line 1. $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +appendText(55); print $q;" <q>55</q>
        $ perl -MXML::LibXML -le " $q = XML::LibXML::Element->new(q{q}); $q-> +removeChildNodes; $q->appendText(55); print $q;" <q>55</q>
Re: Update an XML node value based on one of the attribute values.
by choroba (Cardinal) on Apr 18, 2014 at 16:04 UTC
    Using XML::XSH2, a wrapper around XML::LibXML:
    open file.xml ; for //*[name()='ReferenceId'][@referenceIDType='FXDD'] set text() 'New + value' ; save :b ;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Update an XML node value based on one of the attribute values.
by Jenda (Abbot) on Apr 18, 2014 at 14:16 UTC
    use strict; use XML::Rules; my $filter = XML::Rules->new( style => 'filter', rules => { ReferenceID => sub { my ($tag, $attr) = @_; if ($attr->{referenceIDType} eq 'FXDD') { $attr->{_content} = "the changed content"; } return $tag => $attr; } } ); $filter->filter(\*DATA); __DATA__ <root> <ReferenceID referenceIDType="FXDD">FXDDILN233</ReferenceID> <ReferenceID referenceIDType="RXDD">FXDDILN233</ReferenceID> </root>

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

[Fatfinger Mis-Post: Please Reap] Re: Update an XML node value based on one of the attribute values.
by AnomalousMonk (Archbishop) on Apr 18, 2014 at 23:31 UTC