Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Deleting XML element using XML::LibXML

by shanu_040 (Sexton)
on Sep 14, 2010 at 12:09 UTC ( [id://860097]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I have an XML file with following dummy data. Seeking help on how to remove an element from XML file using XML::LibXML.

Condition to remove element

If value of uid is equal to input value then remove corresponding document element.

<searchresult> <document id="3404"> <uid>16b3</uid> <title><![CDATA[Title1]]></title> <author><![CDATA[Author1]]></author> <date><![CDATA[2010]]></date> <source><![CDATA[Source1]]></source> <volume><![CDATA[1]]></volume> <issue><![CDATA[1]]></issue> <snippet><![CDATA[Snippet]]></snippet> <abstract_url><![CDATA[http://yourhost.com/ar1]]></abstract_url> <fulltext_url><![CDATA[http://yourhost.com/ft1]]></fulltext_url> <resource> <longname><![CDATA[Name1]]></longname> </resource> <nativesearch_url><![CDATA[http://yourhost.com/n1]]></nativesearch_url +> </document> <document id="3404"> <uid>3cdd</uid> <title><![CDATA[Title2]]></title> <author><![CDATA[Author2]]></author> <date><![CDATA[2010]]></date> <source><![CDATA[Source2]]></source> <volume><![CDATA[2]]></volume> <issue><![CDATA[2]]></issue> <snippet><![CDATA[Snippet]]></snippet> <abstract_url><![CDATA[http://yourhost.com/ar1]]></abstract_url> <fulltext_url><![CDATA[http://yourhost.com/ft1]]></fulltext_url> <resource> <longname><![CDATA[Name1]]></longname> </resource> <nativesearch_url><![CDATA[http://yourhost.com/n1]]></nativesearch_url +> </document> <document id="3404"> <uid>446d</uid> <title><![CDATA[Title1]]></title> <author><![CDATA[Author1]]></author> <date><![CDATA[2010]]></date> <source><![CDATA[Source1]]></source> <volume><![CDATA[1]]></volume> <issue><![CDATA[1]]></issue> <snippet><![CDATA[Snippet]]></snippet> <abstract_url><![CDATA[http://yourhost.com/ar1]]></abstract_url> <fulltext_url><![CDATA[http://yourhost.com/ft1]]></fulltext_url> <resource> <longname><![CDATA[Name1]]></longname> </resource> <nativesearch_url><![CDATA[http://yourhost.com/n1]]></nativesearch_url +> </document> </searchresult>

Any help would be greatly appreciated.

Thanks

Replies are listed 'Best First'.
Re: Deleting XML element using XML::LibXML
by ikegami (Patriarch) on Sep 14, 2010 at 23:51 UTC
    my $root = $doc->documentElement(); for my $node ($root->findnodes( '/searchresult/document[ uid/text()="16b3" ]' )) { $node->parent()->removeChild($node); }

    The square brackets in the XPath are like a WHERE clause in SQL.

Re: Deleting XML element using XML::LibXML
by marto (Cardinal) on Sep 14, 2010 at 12:18 UTC
Re: Deleting XML element using XML::LibXML
by graff (Chancellor) on Sep 14, 2010 at 23:10 UTC
    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.

Re: Deleting XML element using XML::LibXML
by choroba (Cardinal) on Sep 14, 2010 at 13:11 UTC
    I prefer XML::XSH2. In it, you can just
    open input.xml ; delete //*[uid='16b3'] ; save :b ;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://860097]
Approved by rovf
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-04-24 07:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found