#!perl -T use strict; use warnings; use Test::More tests => 17; BEGIN { use_ok( 'XML::Rules' ); } my $xml = <<'*END*'; Jane Luser JLuser@bogus.com
Washington st. Old Creek The US bleargh
123-456-7890 663-486-7890 663-486-7000
John Other JOther@silly.com
Grant's st. New Creek Canada sdrysdfgtyh degtrhy degtrhy werthywerthy drthyu
663-486-7891
*END* { #1 my $parser = new XML::Rules ( rules => [ _default => 'content', '^bogus' => undef, # means "ignore" address => sub {address => "$_[1]->{street}, $_[1]->{city} ($_[1]->{country})"}, person => sub { #print Dumper($_[2], $_[3]); return '@person' => "$_[1]->{lname}, $_[1]->{fname}\n<$_[1]->{email}>\n$_[1]->{address}" }, doc => sub { join "\n\n", @{$_[1]->{person}} }, ] ); ok(($parser and ref($parser)), 'Create 1st parser'); my $result = $parser->parsestring($xml) . "\n"; my $correct = <<'*END*'; Luser, Jane Washington st., Old Creek (The US) Other, John Grant's st., New Creek (Canada) *END* is ($result, $correct, "Convert XML to text"); } { #2 my $foo_count = 0; my $parser = new XML::Rules ( rules => [ _default => 'content', # bogus => '', # means "returns no value. The subtags ARE processed. '^bogus' => '', # means "ignore". The subtags ARE NOT processed. phones => undef, address => 'no content', person => 'no content array', doc => sub {$_[1]->{person}}, #'pass no content', foo => sub {$foo_count++;return}, ] ); ok(($parser and ref($parser)), 'Create 2nd parser'); my $result = $parser->parsestring($xml); my $correct = [ { 'email' => 'JLuser@bogus.com', 'lname' => 'Luser', 'fname' => 'Jane', 'address' => { 'country' => 'The US', 'city' => 'Old Creek', 'street' => 'Washington st.' } }, { 'email' => 'JOther@silly.com', 'lname' => 'Other', 'fname' => 'John', 'address' => { 'country' => 'Canada', 'city' => 'New Creek', 'street' => 'Grant\'s st.' } } ]; is_deeply($result, $correct, "Convert XML to structure"); is( $foo_count, 0, "The tag should be ignored as it's only inside "); } { #3 my $buff; open my $OUT, '>', \$buff; my $parser = new XML::Rules ( rules => { _default => 'content', '^bogus' => undef, # means "ignore" address => 'no content', person => sub { print $OUT <<"*END*"; Person: $_[1]->{fname} $_[1]->{lname} Email: $_[1]->{email} Address: $_[1]->{address}{street} $_[1]->{address}{city} $_[1]->{address}{country} *END* return '+count' => 1; }, doc => sub {print $OUT "Printed $_[1]->{count} addresses.\n";return}, } ); ok(($parser and ref($parser)), 'Create 3rd parser'); my $result = $parser->parsestring($xml); my $correct = <<'*END*'; Person: Jane Luser Email: JLuser@bogus.com Address: Washington st. Old Creek The US Person: John Other Email: JOther@silly.com Address: Grant's st. New Creek Canada Printed 2 addresses. *END* is ($buff, $correct, "Convert XML to text, print each completed "); is ($result, undef, "Nothing to return"); } { #4 my $buff; open my $OUT, '>', \$buff; my $parser = new XML::Rules ( rules => { _default => sub {$_[0] => $_[1]->{_content}}, 'fname,lname' => sub {$_[0] => $_[1]->{_content}}, '^bogus' => undef, address => sub {address => "$_[1]->{street}, $_[1]->{city} ($_[1]->{country})"}, phone => sub {$_[1]->{type} => $_[1]->{_content}}, # let's use the "type" attribute as the key and the content as the value phones => sub {delete $_[1]->{_content}; %{$_[1]}}, # remove the text content and pass along the type => content from the child nodes person => sub { # lets print the values, all the data is readily available in the attributes print $OUT "$_[1]->{lname}, $_[1]->{fname} <$_[1]->{email}>\n"; print $OUT "Home phone: $_[1]->{home}\n" if $_[1]->{home}; print $OUT "Office phone: $_[1]->{office}\n" if $_[1]->{office}; print $OUT "Fax: $_[1]->{fax}\n" if $_[1]->{fax}; print $OUT "$_[1]->{address}\n\n"; return; # the tag is processed, no need to remember what it contained }, } ); ok(($parser and ref($parser)), 'Create 4th parser'); my $result = $parser->parsestring($xml); my $correct = <<'*END*'; Luser, Jane Home phone: 123-456-7890 Office phone: 663-486-7890 Fax: 663-486-7000 Washington st., Old Creek (The US) Other, John Office phone: 663-486-7891 Grant's st., New Creek (Canada) *END* is ($buff, $correct, "Convert XML to text, print each completed , simplify address"); } { #5 my $foo_count = 0; my $parser = new XML::Rules ( rules => [ _default => 'content', '^bogus' => undef, # means "ignore" phones => undef, address => sub {delete $_[1]->{_content}; $_[1]}, person => 'as array', doc => 'pass no content', foo => sub {$foo_count++;return;}, '/^.name$/' => sub {$_[0] => $_[1]->{_content}}, ] ); ok(($parser and ref($parser)), 'Create 5th parser'); my $result = $parser->parsestring($xml); my $correct = { 'person' => [ { 'email' => 'JLuser@bogus.com', '_content' => [ "\n \n \n \n ", { 'country' => 'The US', 'city' => 'Old Creek', 'street' => 'Washington st.' }, "\n \n " ], 'lname' => 'Luser', 'fname' => 'Jane' }, { 'email' => 'JOther@silly.com', '_content' => [ "\n \n \n \n ", { 'country' => 'Canada', 'city' => 'New Creek', 'street' => 'Grant\'s st.' }, "\n \n " ], 'lname' => 'Other', 'fname' => 'John' } ] }; is_deeply($result, $correct, "Convert XML to structure"); } { # 6 my $xml = <<'*END*'; Valka s mloky Karel Capek It's really something and I have to underline it. Predtucha Pujmanova It's really a stupid pointless book. Confront this one. And don't read this one please! *END* my $buff; open my $OUT, '>', \$buff; my $parser = new XML::Rules ( rules => [ _default => 'content', u => sub {my $str = $_[1]->{_content}; $str =~ tr/ /_/; return '_'.$str.'_'}, b => sub {my $str = $_[1]->{_content}; return '*'.$str.'*'}, link => sub { qq{$_[1]->{_content}} }, description => sub {my $desc = $_[1]->{_content}; $desc =~ s/^\s+//;$desc =~ s/\s+$//; return 'description' => $desc}, book => sub { my $desc = $_[1]->{description}; $desc =~ s/\n/\n\t/g; print $OUT "Book: $_[1]->{name}\nAuthor: $_[1]->{author}\nDescription: $desc\n\n"; }, ], ); $parser->parsestring($xml); my $correct = <<'*END*'; Book: Valka s mloky Author: Karel Capek Description: It's really *something* and I have to _underline_it_. Book: Predtucha Author: Pujmanova Description: It's really a _stupid_ pointless book. Confront this one. And don't read this one please! *END* is ($buff, $correct, "Convert XML to text, print each completed "); } { #7 my $xml = <<'*END*'; Chiao Ahoj Hola Chao Hi Hello Hasta luego Nashle Dosvidania Farewell *END* my $parser = new XML::Rules ( rules => [ 'x' => sub {'.x' => $_[1]->{_content} . ', '}, bar => sub {$_[1]->{x} =~ s/, $//; return $_[1]->{id} => $_[1]->{x}}, foo => 'pass no content', ] ); my $result = $parser->parsestring($xml); my $correct = { 'GoodBye' => 'Hasta luego, Nashle, Dosvidania, Farewell', 'hello' => 'Chiao, Ahoj, Hola, Chao, Hi, Hello' }; is_deeply($result, $correct, "Test '.attrname'"); } { #8 my $xml = <<'*END*'; 7 3 -6 5 4 *END* my $parser = new XML::Rules ( rules => [ 'times' => sub {'*_content' => $_[1]->{_content}}, 'plus' => sub {'+_content' => $_[1]->{_content}}, 'doc' => 'pass trim', ] ); my $result = $parser->parsestring($xml); my $correct = 7*3 -6 + (5 * 4); is($result, $correct, "Test '+attrname' and '*attrname'"); } { #9 my $xml = <<'*END*'; 1 2 3 4 *END* my $buff; open my $OUT, '>', \$buff; my $parser = new XML::Rules ( rules => [ 'bar' => sub {print $OUT "Found $_[1]->{_content}, preset is $_[3]->[-1]{preset}\n"; return}, '^foo' => sub {$_[1]->{preset} = 12345; return ($_[1]->{status} eq 'on')}, 'foo' => '', 'doc' => '', ] ); $parser->parsestring($xml); close $OUT; my $correct = <<'*END*'; Found 1, preset is 12345 Found 4, preset is 12345 *END* is($buff, $correct, "Test '^tagname' rules"); }