in reply to Re: XML parsing
in thread XML parsing

Perhaps you can help me with Twig, then. What I want to do is search within a parent node for a specific text content of an element. If it doesnt match the string, then delete the entire parent node. Here's an example:
<book> <book1>Book1</book1> <title>Title of Book 1</title> <genre>Fantasy</genre> </book>
What I'd like to do in this case is search within each <book> and see if the title matches "Title of Book 1". If it doesn't, I want that entire <book> deleted. Does this make sense?

Replies are listed 'Best First'.
Re^3: XML parsing
by Anonymous Monk on Oct 03, 2014 at 19:44 UTC

    See the section "Building an XML filter" of XML::Twig. Here's a quick implementation:

    use XML::Twig; open my $ofh, '>', $output_filename or die $!; XML::Twig->new( twig_print_outside_roots => $ofh, keep_spaces => 1, twig_roots => { book => sub { my ($twig, $book) = @_; if ($book->first_child_text('title') eq 'Title of Book 1') { $book->flush($ofh); } else { $book->purge; } return 1; } }, )->parsefile($input_filename); close $ofh;
Re^3: XML parsing
by jellisii2 (Hermit) on Oct 06, 2014 at 12:26 UTC
    I would say that your example is probably over simplistic, so I've expanded on and cleaned it up slightly:
    <library> <book> <book1>Book1</book1> <title>Title of Book 1</title> <genre>Fantasy</genre> </book> <book> <book2>Book2</book2> <title>Not the Title of Book 1</title> <genre>Fantasy</genre> </book> </library>

    Now that we have something that's a little bit easier to show off some stuff, here's an example that does exactly what you ask.
    use strict; use warnings; use XML::Twig; use Data::Dumper; my $DATA = ' <library> <book> <book1>Book1</book1> <title>Title of Book 1</title> <genre>Fantasy</genre> </book> <book> <book2>Book2</book2> <title>Not the Title of Book 1</title> <genre>Fantasy</genre> </book> </library> '; my $source_twig = XML::Twig->new('pretty_print' => 'indented'); $source_twig->safe_parse($DATA); foreach my $book ($source_twig->root->children('book')) { if ($book->first_child('title')->text() ne 'Title of Book 1') { $book->cut() } } $source_twig->print();

    And it's output:
    <library> <book> <book1>Book1</book1> <title>Title of Book 1</title> <genre>Fantasy</genre> </book> </library>