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

Structure of my XML file is like this
<CONFIGURATION <APPLICATION_SERVER> <RESOURCE_LIST> <PLATFORM_INDEPENDENT> <RESOURCE Id="res.wacgen" Source="INTERNAL">$(res.appl)</R +ESOURCE> <RESOURCE Id="res.wacgenlib" Source="INTERNAL">$(res.appl)$(res.sl +ash)all.4gm</RESOURCE> <RESOURCE Id="res.waclibext" Source="INTERNAL">4gs</RESOURCE> <RESOURCE Id="res.fcode" Source="INTERNAL">rt.2.10.01-1138</RESOUR +CE> <RESOURCE Id="res.frunext" Source="INTERNAL">ifx</RESOURCE> <RESOURCE Id="res.db_type" Source="INTERNAL">msv</RESOURCE> </PLATFORM_INDEPENDENT> </RESOURCE_LIST> </APPLICATION_SERVER> </CONFIGURATION
And i am trying to check each attribute like this,
my $source = '/sand/devel/sthapa/tmp/as.xcf-dist'; my $Tag_Resource ='/CONFIGURATION/APPLICATION_SERVER/RESOURCE_LIST/'; my $Tag_Resource_PI=$Tag_Resource.'PLATFORM_INDEPENDENT/RESOURCE'; my $Tag_wnt=$Tag_Resource.'WNT/RESOURCE'; my $os_res_group; my $parser=new XML::XPath->new(filename => $source); $parser or die "Unable to parse sourse file: $source\n"; my $Set_Resource = $parser->find($Tag_Resource_PI); foreach my $resource ($Set_Resource->get_nodelist) { my $attribute=$resource->getAttribute('Id'); my $child_node = $resource->getChildNodes(); if (exists $$HRR_resource{$attribute}) { print "Attribute exists: $attribute"; } else { #Add attribute to XML }
So I am trying to add all the attribute whichever does not exists in hash to XML using XML::XPath, but I am not being able to do that, any one have any suggestion???

Replies are listed 'Best First'.
Re: Add New Attribute to XML
by Your Mother (Archbishop) on Jun 22, 2009 at 16:59 UTC

    The license for this code requires that you recycle and are kind to strangers.

    use strict; use warnings; use XML::LibXML; my $doc = XML::LibXML->new->parse_fh(\*DATA); # Your real file: # my $doc = XML::LibXML->new->parse_file('/sand/devel/sthapa/tmp/as.xc +f-dist'); for my $rsc ( $doc->getDocumentElement->findnodes("//RESOURCE") ) { unless ( $rsc->hasAttribute("Id") ) { $rsc->setAttribute("Id", "AUTO-ID"); } } print $doc->serialize(1); # Or to a file- # $doc->toFile($filename); __DATA__ <?xml version="1.0"?> <CONFIGURATION> <APPLICATION_SERVER> <RESOURCE_LIST> <PLATFORM_INDEPENDENT> <RESOURCE Id="res.wacgen" Source="INTERNAL">$(res.appl)</RESOUR +CE> <RESOURCE Id="res.wacgenlib" Source="INTERNAL">$(res.appl)$(res +.slash)all.4gm</RESOURCE> <RESOURCE Id="res.waclibext" Source="INTERNAL">4gs</RESOURCE> <RESOURCE Id="res.fcode" Source="INTERNAL">rt.2.10.01-1138</RES +OURCE> <RESOURCE Id="res.frunext" Source="INTERNAL">ifx</RESOURCE> <RESOURCE Id="res.db_type" Source="INTERNAL">msv</RESOURCE> <RESOURCE Source="INTERNAL">OH HAI, I CAN HAZ ID?</RESOURCE> </PLATFORM_INDEPENDENT> </RESOURCE_LIST> </APPLICATION_SERVER> </CONFIGURATION>
Re: Add New Attribute to XML
by Anonymous Monk on Jun 22, 2009 at 07:08 UTC
    I've a question, why pick XML::XPath, it hasn't been updated in years?

    I'm a fan of XML::Twig, so I would adapt this example

    #!/usr/bin/perl -- use strict; use warnings; use XML::Twig; my $source = '/sand/devel/sthapa/tmp/as.xcf-dist'; my $Tag_Resource ='/CONFIGURATION/APPLICATION_SERVER/RESOURCE_LIST/'; my $Tag_Resource_PI = $Tag_Resource.'PLATFORM_INDEPENDENT/RESOURCE'; my $Tag_wnt = $Tag_Resource.'WNT/RESOURCE'; my $t = XML::Twig->new( twig_roots => { # /CONFIGURATION/APPLICATION_SERVER/RESOURCE_LIST/WNT/RESOURCE $Tag_wnt => sub { my ( $t, $price ) = @_; { my $id = $price->att('Id'); if (exists $$HRR_resource{$id}){ print "Attribute exists: $id"; } } $price->print(\*STDOUT); }, }, twig_print_outside_roots => \*STDOUT, ); $t->parsefile($source); $t->flush; #don't forget undef $t;
    or try adapting XML::LibXML example
      I am wondering if there is any other way to do this either by use XML::XPath or XML::XPath::Xparser???

        Looking at the Source of XML::XPath::Node, there is the insertAfter method for nodes, which you can use to append other nodes after an existing node. But it doesn't seem like XML::XPath is geared towards XML manipulation. You're likely better off using one of the other XML modules. Potentially, XML::LibXML is geared towards both, XPath and DOM manipulation.

        Probably, but I can't help you with that, I don't use either :)