in reply to Re: xml remove attribute
in thread xml remove attribute

OK, got a result, but not easily. I seem to be missing how to descend an xml tree and pick out the element I want to operate on. What I have is:
#!/usr/bin/perl use strict; use warnings; use XML::LibXML; die "Usage: $0 filename \n"; unless ( @ARGV > 0 ); my $xml_file = shift; my $xml = XML::LibXML->new; my $dom = $xml->parse_file( $xml_file ); my $root = $dom->documentElement; my @logins = grep { $_->nodeType == XML_ELEMENT_NODE } $root->childNod +es; foreach my $login ( @logins ) { my @user_infos = grep { $_->nodeType == XML_ELEMENT_NODE } $login-> +childNodes; foreach my $user_info ( @user_infos ) { my @add_users = grep { $_->nodeType == XML_ELEMENT_NODE } $user_ +info->childNodes; foreach my $add_user ( @add_users ) { $add-user->removeAttribute( "USER_NAME" ); $add-user->removeAttribute( "PASSWORD" ); } } } my $output = $dom->toString(0); $output =~ s/(?<=\n)\s*\n//g; open ( my $FH, '>', 'newilo2' ) or die "Could not open file newilo2 $! +"; print $FH $output; close $FH;
I tried using findnode, but I get an error about perl not being able to find that method. So, thanks for the pointer! It at least is getting me the results I want. :)

Replies are listed 'Best First'.
Re^3: xml remove attribute
by hippo (Archbishop) on Aug 19, 2016 at 16:47 UTC

    No need to do a nested descent through the tree when you know in advance which nodes you want to alter. This revised version of your code does the trick for your sample data:

    #!/usr/bin/perl use strict; use warnings; use XML::LibXML; die "Usage: $0 filename \n" unless ( @ARGV > 0 ); my $xml_file = shift; my $xml = XML::LibXML->new; my $dom = $xml->parse_file( $xml_file ); foreach my $add_user ( $dom->getElementsByTagName('ADD_USER') ) { $add_user->removeAttribute( "USER_NAME" ); $add_user->removeAttribute( "PASSWORD" ); } my $output = $dom->toString(0); $output =~ s/(?<=\n)\s*\n//g; open ( my $FH, '>', 'newilo2' ) or die "Could not open file newilo2 $! +"; print $FH $output; close $FH;

    XML::LibXML is pretty powerful, but it's a steep old learning curve. If you do a lot of XML work it would pay to immerse yourself in the documentation for a while to let it all sink in. Good luck.

    Edit: better choice of verb

      Great! Yes, still reading. :) Now, I have the USER_LOGINs that I want to delete. In order to do that, I need to change the element name from ADD_USER to DEL_USER. Ah, found http://www.perlmonks.org/?node_id=838120. That pointed me in the right direction. I added: $add_user->setNodeName( "DEL_USER" ); to the last line in my 'foreach my $add_user' loop. That did it! :) Thanks again for the help!!