While I normally agree with the sentiment of the first reply (you should show us the code that you tried), I'm also unable to resist the temptation to try things out with XML::LibXML, because it's so awesome. (And also, your particular task is the sort of thing I'm likely to come across at some point.)
The following is one possible solution; it's probably not the most "elegant" or "parsimonious", but it does what you describe for the kind of xml stream you have:
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
die "Usage: $0 file.xml bad_uid ...\n"
unless ( @ARGV > 1 );
my $xml_file = shift;
my %bad_uids = map { $_ => undef } @ARGV;
my $xml = XML::LibXML->new;
my $dom = $xml->parse_file( $xml_file );
my @kill_list;
for my $document ( $dom->getElementsByTagName( "document" )) {
my ( $uid ) = $document->getElementsByTagName( "uid" );
push @kill_list, $document if ( exists( $bad_uids{ $uid->textConte
+nt } ));
}
warn sprintf( "Removing %d document elements from %s\n",
scalar @kill_list, $xml_file );
$_->unbindNode for ( @kill_list );
rename $xml_file, "$xml_file.old" or die "Unable to rename $xml_file\n
+";
open( NEW, ">", $xml_file ) or die "Unable to write new $xml_file\n";
print NEW $dom->toString;
close NEW;
You would run that script as a shell command, with 2 or more command line args: the name of the file to edit, and one or more "uid" values to be removed.
I realize that by providing a complete solution like this, I may be denying you the joy and satisfaction of reading the XML::LibXML manuals and doing experimentation on your own to reach your goal. If that's the case, I deeply regret it. (Those man pages are really really good.)
Please do explore the man pages for this module and its various sub-modules, because you will learn a lot from them. Rest assured that LibXML would most likely give you other ways to do this task that may be better for your particular needs. |