XML-Twig-3.50/ 0000755 0001750 0001750 00000000000 12637027512 013260 5 ustar mrodrigu mrodrigu XML-Twig-3.50/MANIFEST 0000644 0001750 0001750 00000020210 12637027273 014410 0 ustar mrodrigu mrodrigu MANIFEST
Makefile.PL
README
Changes
Twig_pm.slow
Twig.pm
Twig/XPath.pm
speedup
filter_for_5.005
check_optional_modules
tools/xml_pp/xml_pp
tools/xml_grep/xml_grep
tools/xml_spellcheck/xml_spellcheck
tools/xml_split/xml_split
tools/xml_merge/xml_merge
t/latin1_accented_char.iso-8859-1
t/test1.t
t/test2.t
t/test2_1.exp
t/test2_1.res
t/test2_1.xml
t/test2_2.dtd
t/test2_2.exp
t/test2_2.res
t/test2_2.xml
t/test2_3.res
t/test3.t
t/test4.t
t/test5.t
t/is_field.t
t/test_nav.t
t/test_additional.t
t/test_class_methods.t
t/test_class_selector.t
t/test_with_lwp.t
t/test_with_lwp.xml
t/test_with_lwp_not_wf.xml
t/test_attregexp_cond.t
t/test_xpath_cond.t
t/test_erase.t
t/test_even_more_coverage.t
t/test_keep_atts_order.t
t/test_mark.t
t/test_ignore_elts.t
t/test_cdata.t
t/test_twig_roots.t
t/test_spaces.t
t/test_simplify.t
t/test_entities.t
t/test_pi_handler.t
t/test_comment_handler.t
t/test_pos.t
t/test_variables.t
t/test_drop_comments.t
t/test_unique_xpath.t
t/dummy.dtd
t/xmlxpath_01basic.t
t/xmlxpath_02descendant.t
t/xmlxpath_03star.t
t/xmlxpath_04pos.t
t/xmlxpath_05attrib.t
t/xmlxpath_06attrib_val.t
t/xmlxpath_07count.t
t/xmlxpath_08name.t
t/xmlxpath_09a_string_length.t
t/xmlxpath_09string_length.t
t/xmlxpath_10pipe.t
t/xmlxpath_12axisdescendant.t
t/xmlxpath_13axisparent.t
t/xmlxpath_14axisancestor.t
t/xmlxpath_15axisfol_sib.t
t/xmlxpath_16axisprec_sib.t
t/xmlxpath_17axisfollowing.t
t/xmlxpath_18axispreceding.t
t/xmlxpath_19axisd_or_s.t
t/xmlxpath_20axisa_or_s.t
t/xmlxpath_21allnodes.t
t/xmlxpath_22name_select.t
t/xmlxpath_23func.t
t/xmlxpath_24namespaces.t
t/xmlxpath_25scope.t
t/xmlxpath_26predicate.t
t/xmlxpath_28ancestor2.t
t/xmlxpath_29desc_with_predicate.t
t/xmlxpath_30lang.t
t/xmlxpath_31vars.t
t/xmlxpath_test_with_handlers.t
t/xmlxpath_xpath_cond.t
t/xmlxpath_additional.t
t/xmlxpath_test_twig_roots.t
t/xmlxpath_nav.t
t/xmlxpath_test1.t
t/xmlxpath_tools.pm
t/test_errors.t
t/test_safe_encode.t
t/pod.t
t/pod_coverage.t
t/test_expand_external_entities.t
t/test_expand_external_entities.xml
t/test_expand_external_entities.dtd
t/test_need_io_scalar.t
t/test_need_use_bytes.t
t/test_need_3_args_open.t
t/test_bugs_3_15.t
t/test_bugs_3_18.t
t/test_bugs_3_19.t
t/test_bugs_3_21.t
t/test_bugs_3_22.t
t/test_error_with_unicode_layer
t/test_new_features_3_15.t
t/test_new_features_3_16.t
t/test_new_features_3_18.t
t/test_new_features_3_22.t
t/test_new_features_3_22.xml
t/test_new_features_3_22.html
t/tests_3_23.t
t/test_3_24.t
t/test_3_26.t
t/test_3_27.t
t/test_3_30.t
t/test_3_32.t
t/test_3_35.t
t/test_3_36.t
t/test_3_38.t
t/test_3_39.t
t/test_3_40.t
t/test_3_41.t
t/test_3_42.t
t/test_3_44.t
t/test_3_45.t
t/test_3_47.t
t/test_3_48.t
t/test_3_50.t
t/test_changes.t
t/test_memory.t
t/test_wrapped.t
t/test_xml_split.t
t/test_xml_split_g.t
t/test_xml_split.xml
t/test_xml_split_entities.xml
t/test_xml_split_w_decl.xml
t/test_xml_split/test_xml_split_expected-1-00.xml
t/test_xml_split/test_xml_split_expected-1-01.xml
t/test_xml_split/test_xml_split_expected-1-02.xml
t/test_xml_split/test_xml_split_expected-1-03.xml
t/test_xml_split/test_xml_split_expected-1-04.xml
t/test_xml_split/test_xml_split_expected-1-05.xml
t/test_xml_split/test_xml_split_expected-2-00.xml
t/test_xml_split/test_xml_split_expected-2-01.xml
t/test_xml_split/test_xml_split_expected-2-02.xml
t/test_xml_split/test_xml_split_expected-2-03.xml
t/test_xml_split/test_xml_split_expected-2-04.xml
t/test_xml_split/test_xml_split_expected-2-05.xml
t/test_xml_split/test_xml_split_expected-3-00.xml
t/test_xml_split/test_xml_split_expected-3-01.xml
t/test_xml_split/test_xml_split_expected-3-02.xml
t/test_xml_split/test_xml_split_expected-3-03.xml
t/test_xml_split/test_xml_split_expected-3-04.xml
t/test_xml_split/test_xml_split_expected-3-05.xml
t/test_xml_split/test_xml_split_expected-3-06.xml
t/test_xml_split/test_xml_split_expected-3-07.xml
t/test_xml_split/test_xml_split_expected-3-08.xml
t/test_xml_split/test_xml_split_expected-3-09.xml
t/test_xml_split/test_xml_split_expected-4-00.xml
t/test_xml_split/test_xml_split_expected-4-01.xml
t/test_xml_split/test_xml_split_expected-4-02.xml
t/test_xml_split/test_xml_split_expected-4-03.xml
t/test_xml_split/test_xml_split_expected-4-04.xml
t/test_xml_split/test_xml_split_expected-4-05.xml
t/test_xml_split/test_xml_split_expected-4-06.xml
t/test_xml_split/test_xml_split_expected-4-07.xml
t/test_xml_split/test_xml_split_expected-4-08.xml
t/test_xml_split/test_xml_split_expected-4-09.xml
t/test_xml_split/test_xml_split_expected-5-00.xml
t/test_xml_split/test_xml_split_expected-5-01.xml
t/test_xml_split/test_xml_split_expected-5-02.xml
t/test_xml_split/test_xml_split_expected-5-03.xml
t/test_xml_split/test_xml_split_expected-6-00.xml
t/test_xml_split/test_xml_split_expected-6-01.xml
t/test_xml_split/test_xml_split_expected-6-02.xml
t/test_xml_split/test_xml_split_expected-6-03.xml
t/test_xml_split/test_xml_split_expected-7-00.xml
t/test_xml_split/test_xml_split_expected-7-01.xml
t/test_xml_split/test_xml_split_expected-7-02.xml
t/test_xml_split/test_xml_split_expected-8-00.xml
t/test_xml_split/test_xml_split_expected-8-01.xml
t/test_xml_split/test_xml_split_expected-8-02.xml
t/test_xml_split/test_xml_split_expected-9-00.xml
t/test_xml_split/test_xml_split_expected-9-01.xml
t/test_xml_split/test_xml_split_expected-9-02.xml
t/test_xml_split/test_xml_split_expected-9-03.xml
t/test_xml_split/test_xml_split_expected-9-04.xml
t/test_xml_split/test_xml_split_expected-9-05.xml
t/test_xml_split/test_xml_split_expected-10-00.xml
t/test_xml_split/test_xml_split_expected-10-01.xml
t/test_xml_split/test_xml_split_expected-10-02.xml
t/test_xml_split/test_xml_split_expected-10-03.xml
t/test_xml_split/test_xml_split_expected-10-04.xml
t/test_xml_split/test_xml_split_expected-10-05.xml
t/test_xml_split/test_xml_split_expected-11-00.xml
t/test_xml_split/test_xml_split_expected-11-01.xml
t/test_xml_split/test_xml_split_expected-12-00.xml
t/test_xml_split/test_xml_split_expected-12-01.xml
t/test_xml_split/test_xml_split_expected-13-00.xml
t/test_xml_split/test_xml_split_expected-13-01.xml
t/test_xml_split/test_xml_split_expected-13-02.xml
t/test_xml_split/test_xml_split_expected-14-00.xml
t/test_xml_split/test_xml_split_expected-14-01.xml
t/test_xml_split/test_xml_split_expected-14-02.xml
t/test_xml_split/test_xml_split_expected-15-00.xml
t/test_xml_split/test_xml_split_expected-15-01.xml
t/test_xml_split/test_xml_split_expected-15-02.xml
t/test_xml_split/test_xml_split_expected-16-00.xml
t/test_xml_split/test_xml_split_expected-16-01.xml
t/test_xml_split/test_xml_split_expected-16-02.xml
t/test_xml_split/test_xml_split_expected-16-03.xml
t/test_xml_split/test_xml_split_expected-16-04.xml
t/test_xml_split/test_xml_split_expected-16-05.xml
t/test_xml_split/test_xml_split_expected-17-00.xml
t/test_xml_split/test_xml_split_expected-17-01.xml
t/test_xml_split/test_xml_split_expected-17-02.xml
t/test_xml_split/test_xml_split_expected-17-03.xml
t/test_xml_split/test_xml_split_expected-17-04.xml
t/test_xml_split/test_xml_split_expected-17-05.xml
t/test_xml_split/test_xml_split_expected-17-06.xml
t/test_xml_split/test_xml_split_expected-17-07.xml
t/test_xml_split/test_xml_split_expected-17-08.xml
t/test_xml_split/test_xml_split_expected-17-09.xml
t/test_xml_split/test_xml_split_expected-18-00.xml
t/test_xml_split/test_xml_split_expected-18-01.xml
t/test_xml_split/test_xml_split_expected-18-02.xml
t/test_xml_split/test_xml_split_expected-18-03.xml
t/test_xml_split/test_xml_split_expected-19-00.xml
t/test_xml_split/test_xml_split_expected-19-01.xml
t/test_xml_split/test_xml_split_expected-19-02.xml
t/test_xml_split/test_xml_split_expected-19-03.xml
t/test_xml_split/test_xml_split_expected-19-04.xml
t/test_xml_split/test_xml_split_expected-19-05.xml
t/test_xml_split/test_xml_split_expected-20-00.xml
t/test_xml_split/test_xml_split_expected-20-01.xml
t/test_xml_split/test_xml_split_expected-21-00.xml
t/test_xml_split/test_xml_split_expected-21-01.xml
t/test_xml_split/test_xml_split_expected-21-02.xml
t/test_xml_split/test_xml_split_expected-21-03.xml
t/test_autoencoding_conversion.t
t/tools.pm
t/zz_dump_config.t
t/test_kwalitee.t
t/test_meta_json.t
t/test_3_41.t
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
XML-Twig-3.50/t/ 0000755 0001750 0001750 00000000000 12637027512 013523 5 ustar mrodrigu mrodrigu XML-Twig-3.50/t/test4.t 0000755 0001750 0001750 00000014146 12346001774 014763 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
use XML::Twig;
my $TMAX=19; # do not forget to update!
print "1..$TMAX\n";
my $s='
';
my @toc;
my $t= new XML::Twig( TwigHandlers => { title => sub { push @toc, $_[1]->text; } });
$t->parse( $s);
my $toc= join ':', @toc;
stest( $toc, "Title bold:Title", "text method");
undef @toc;
$t= new XML::Twig( TwigHandlers => { title => sub { push @toc, $_[1]->sprint( 1); } });
$t->parse( $s);
$toc= join ':', @toc;
stest( $toc, "Title bold :Title", "sprint method");
undef @toc;
$t= new XML::Twig( TwigHandlers => { title => sub { push @toc, $_[1]->sprint( 1);
$_[0]->purge; } });
$t->parse( $s);
$toc= join ':', @toc;
stest( $toc, "Title bold :Title", "sprint method with purge");
my $purged_doc= $t->sprint;
stest( $purged_doc, ' ', "sprint purged doc");
$t= new XML::Twig( TwigRoots => { title => 1});
$t->parse( $s);
my $doc= $t->sprint;
stest( $doc, 'Title bold Title ', "using title as TwigRoots");
$t= new XML::Twig( TwigHandlers => { doc => sub { $_[1]->set_att( mod => "yes"); } },
TwigRoots => { title => 1});
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, 'Title bold Title ', "using title as TwigRoots (with doc handler)");
$s='
';
$t= new XML::Twig( TwigHandlers => { doc => sub { $_[1]->set_att( mod => "yes"); } },
TwigRoots => { title => 1});
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, 't1 b1 ts1 b2 t2 ts2 ', "using title as TwigRoots (with doc handler)");
$t= new XML::Twig( TwigHandlers => { doc => sub { $_[1]->set_att( mod => "yes"); } },
TwigRoots => { title => 1, p2 => 1});
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, 't1 b1 ts1 b2 para1 t2 para4 ts2 ', "using title, p2 as TwigRoots (with doc handler)");
$s="string with ' here ";
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, "string with ' here ", "apos without KeepEncoding");
$t= new XML::Twig( KeepEncoding => 1);
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, "string with ' here ", "apos WITH KeepEncoding");
$s="string with " here ";
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, "string with \" here ", "quote without KeepEncoding");
$t= new XML::Twig( KeepEncoding => 1);
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, 'string with " here ', "quote WITH KeepEncoding");
$s="string with & here ";
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, $s, "& in text");
$s='string ';
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, $s, "& in attribute");
$s="string with < here ";
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, $s, "< in text");
$s='string ';
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, $s, "< in attribute");
$s="string with " here ";
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, 'string with " here ', "" in text");
$s='string ';
$t= new XML::Twig();
$t->parse( $s);
$doc= $t->sprint;
stest( $doc, $s, "" in attribute");
#$s='string ';
#$t= new XML::Twig();
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, $s, " in attribute");
#$s="string with ‰ here ";
#$t= new XML::Twig();
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, "string with here ", "eacute without KeepEncoding");
#$t= new XML::Twig( KeepEncoding => 1);
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, 'string with ‰ here ', "eacute WITH KeepEncoding");
#$s='string with here ';
#$t= new XML::Twig();
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, "string with here ", " without KeepEncoding");
#$t= new XML::Twig( KeepEncoding => 1);
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, 'string with here ', " WITH KeepEncoding");
#$s='text ';
#$t= new XML::Twig();
#$t->parse( $s);
#$doc= $t->sprint;
#stest( $doc, $s, "PI");
if( $] > 5.008)
{ my (@called);
my $t= XML::Twig->new(
twig_handlers =>
{ a => sub { push @called, 'a'; 1; },
'b/a' => sub { push @called, 'b/a'; 1; },
'/b/a' => sub { push @called, '/b/a'; 1; },
'/a' => sub { push @called, '/a'; 1; },
},
);
$t->parse( ' ');
my $calls= join( ':', @called);
my $expected= "/b/a:b/a:a";
if( $calls eq $expected) { print "ok 19\n"; }
else { print "not ok 19\n"; warn "\n[$calls] instead of [$expected]\n"; }
}
else
{ warn "skipped for perl < 5.8\n"; print "ok 19\n"; }
exit 0;
XML-Twig-3.50/t/xmlxpath_additional.t 0000755 0001750 0001750 00000014173 12346001775 017756 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use strict;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
BEGIN
{ if( eval( 'require XML::Twig::XPath'))
{ import XML::Twig::XPath; }
elsif( $@ =~ m{^cannot use XML::XPath or XML::XPathEngine})
{ print "1..1\nok 1\n"; warn no_xpath_engine();
exit;
}
else
{ die $@; }
}
print "1..75\n";
use XML::Twig::XPath;
ok(1, "loading");
{
my $t= XML::Twig::XPath->new->parse( '5 ');
is( $t->to_number->as_string, 5, "to_number");
}
{
my $t= XML::Twig::XPath->new->parse( '5
');
is( $t->first_elt( 'p')->to_number->as_string, 5, "element to_number");
is( $t->getValue, 5, '$t->getValue');
}
{
my $t= XML::Twig::XPath->new->parse( 'foo
');
is( $t->first_elt( 'p')->to_number->as_string, "NaN", "to_number (NaN)");
}
{
my $t= XML::Twig::XPath->new->parse( 'p1
toto :p2
e1 :e2
e3 :e4
');
is( $t->findnodes_as_string( '//p'), '
p1
:p2
', "findnodes_as_string");
is( $t->root->findnodes_as_string( '//p'), 'p1
:p2
', "findnodes_as_string");
is( $t->root->findnodes_as_string( 'p'), 'p1
:p2
', "findnodes_as_string (from root)");
if( defined( $XML::XPathEngine::VERSION) ||
( $XML::XPath::VERSION && (($XML::XPath::VERSION eq '1.13.1') || $XML::XPath::VERSION >= 1.13) )
)
{ ok( $t->root->exists( '//p'), "exists //p (on root)");
ok( $t->exists( '//p'), "exists //p (on root)");
}
else
{ skip( 2, "your version of XML::XPath has a bug in the 'exists' method, you cannot use it with XML::Twig::XPath"); }
my $p= $t->first_elt( 'p');
ok( $p->matches( 'p'), "\$p->matches( 'p')");
ok( $t->matches( '//p', $p), "\$p->matches( 'p') (from the twig)");
my $p2_set= $t->root->find( 'p[text()= ":p2"]');
is( $p2_set->size, 1, "find 1 node");
is( $p2_set->to_literal, ':p2', 'p2 text');
my $s_set= $t->find( '//s[e/text()= ":e2"]');
is( $s_set->size, 1, "find 1 s node (nodeset)");
my @s= $s_set->get_nodelist;
is( scalar @s, 1, "find 1 s node nodelist");
my $s= shift @s;
is( $s->getValue, 'e1:e2', 's text');
}
{
my $t= XML::Twig::XPath->new( pi => 'process', comments => 'process')
->parse( 'text
foobar
');
nok( $t->isElementNode, '$t isElementNode');
nok( $t->isAttributeNode, '$t isAttributeNode');
nok( $t->isTextNode, '$t isTextNode');
nok( $t->isProcessingInstructionNode, '$t isProcessingInstructionNode');
nok( $t->isPINode, '$t isPINode');
nok( $t->isCommentNode, '$t isCommentNode');
nok( $t->isNamespaceNode, '$t isNamespaceNode');
ok( $t->getAttributes, '$t->getAttributes');
my $root= $t->root;
ok( $root->isElementNode, '$root isElementNode');
nok( $root->isAttributeNode, '$root isAttributeNode');
nok( $root->isTextNode, '$root isTextNode');
nok( $root->isProcessingInstructionNode, '$root isProcessingInstructionNode');
nok( $root->isPINode, '$root isPINode');
nok( $root->isCommentNode, '$root isCommentNode');
nok( $root->isNamespaceNode, '$root isNamespaceNode');
my $p= $t->first_elt( 'p');
ok( $p->isElementNode, '$p isElementNode');
nok( $p->isAttributeNode, '$p isAttributeNode');
nok( $p->isTextNode, '$p isTextNode');
nok( $p->isProcessingInstructionNode, '$p isProcessingInstructionNode');
nok( $p->isPINode, '$p isPINode');
nok( $p->isCommentNode, '$p isCommentNode');
nok( $p->isNamespaceNode, '$p isNamespaceNode');
my @att= $p->getAttributes;
my $att= shift @att;
is( $att->getName, 'att', '$att->getName');
is( $att->getValue, 'foo', '$att->getValue');
is( $att->toString, 'att="foo"', '$p attribute');
nok( $att->isElementNode, '$att isElementNode');
ok( $att->isAttributeNode, '$att isAttributeNode');
nok( $att->isTextNode, '$att isTextNode');
nok( $att->isProcessingInstructionNode, '$att isProcessingInstructionNode');
nok( $att->isPINode, '$att isPINode');
nok( $att->isCommentNode, '$att isCommentNode');
nok( $att->isNamespaceNode, '$att isNamespaceNode');
my $comment=$t->first_elt( '#COMMENT');
nok( $comment->isElementNode, '$comment isElementNode');
nok( $comment->isAttributeNode, '$comment isAttributeNode');
nok( $comment->isTextNode, '$comment isTextNode');
nok( $comment->isProcessingInstructionNode, '$comment isProcessingInstructionNode');
nok( $comment->isPINode, '$comment isPINode');
ok( $comment->isCommentNode, '$comment isCommentNode');
nok( $comment->isNamespaceNode, '$comment isNamespaceNode');
my $pi=$t->first_elt( '#PI');
nok( $pi->isElementNode, '$pi isElementNode');
nok( $pi->isAttributeNode, '$pi isAttributeNode');
nok( $pi->isTextNode, '$pi isTextNode');
ok( $pi->isProcessingInstructionNode, '$pi isProcessingInstructionNode');
ok( $pi->isPINode, '$pi isPINode');
nok( $pi->isCommentNode, '$pi isCommentNode');
nok( $pi->isNamespaceNode, '$pi isNamespaceNode');
is( $t->findvalue( '//foo:bar'), 'foobar', '//foo:bar');
is( $t->findvalue( '//*[@foo:att]'), 'foobar', '//*[@foo:att');
is( $t->findvalue( '//*[@foo:att=1]'), 'foobar', '//*[@foo:att=1]');
is( $t->findvalue( '//*[@foo:att=2]'), '', '//*[@foo:att=2]');
my $twig= ($root->findnodes( '..'))[0];
ok( UNIVERSAL::isa( $twig, 'XML::Twig'), 'findnodes returning the document node (' . ref( $twig) . ')');
my $back_to_root= ($root->findnodes( '../*'))[0];
is( $back_to_root->gi, 'doc' , 'findnodes returning the root through the document node');
}
# test namespace methods
{ my $ns= XML::Twig::XPath::Namespace->new( foo => "uri");
ok( $ns->isNamespaceNode, '$ns isNamespaceNode');
is( $ns->getPrefix, 'foo', 'getPrefix');
is( $ns->getExpanded, 'uri', 'getExpanded');
is( $ns->getValue, 'uri', 'getValue');
is( $ns->getData, 'uri', 'getData');
}
# check that set_text works also with XML::Twig::XPath
{ my $elt= XML::Twig::XPath::Elt->new( p => "foo");
$elt->set_text( "bar");
ok( 1, "set_text using XML::Twig::XPath");
}
exit 0;
XML-Twig-3.50/t/xmlxpath_17axisfollowing.t 0000755 0001750 0001750 00000001303 12346001775 020672 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
use Test;
plan( tests => 4);
use XML::Twig::XPath;
ok(1);
my $t= XML::Twig::XPath->new->parse( \*DATA);
ok( $t);
my @nodes;
@nodes = $t->findnodes( '/AAA/XXX/following::*');
ok(@nodes, 2);
@nodes = $t->findnodes( '//ZZZ/following::*');
ok(@nodes, 12);
exit 0;
__DATA__
XML-Twig-3.50/t/xmlxpath_20axisa_or_s.t 0000755 0001750 0001750 00000001027 12346001775 020131 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
use Test;
plan( tests => 4);
use XML::Twig::XPath;
ok(1);
my $t= XML::Twig::XPath->new->parse( \*DATA);
ok( $t);
my @nodes;
@nodes = $t->findnodes( '/AAA/XXX/DDD/EEE/ancestor-or-self::*');
ok(@nodes, 4);
@nodes = $t->findnodes( '//GGG/ancestor-or-self::*');
ok(@nodes, 5);
exit 0;
__DATA__
XML-Twig-3.50/t/test_3_24.t 0000755 0001750 0001750 00000006636 12346001774 015433 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
my $DEBUG=0;
use XML::Twig;
my $TMAX=15;
print "1..$TMAX\n";
{ # adding comments or pi's before/after the root
my $doc= XML::Twig->nparse( ' ');
my $xsl = XML::Twig::Elt->new('#PI');
$xsl->set_target('xml-stylesheet');
$xsl->set_data('type= "text/xsl" href="xsl_style.xsl"');
$xsl->paste( before => $doc->root);
is( $doc->sprint, ' ',
'PI before the root'
);
my $comment= XML::Twig::Elt->new( '#COMMENT');
$comment->set_comment( 'foo');
$comment->paste( before => $doc->root);
is( $doc->sprint, ' ',
'Comment before the root'
);
XML::Twig::Elt->new( '#COMMENT')->set_comment( 'bar')->paste( after => $doc->root);
XML::Twig::Elt->new( '#PI')->set_target( 'foo')->set_data( 'bar')->paste( after => $doc->root);
is( $doc->sprint, ' ',
'Pasting things after the root'
);
}
{ # adding comments or pi's before/after the root
my $doc= XML::Twig->nparse( ' ');
$doc->add_stylesheet( xsl => 'xsl_style.xsl');
is( $doc->sprint, ' ', 'add_stylesheet');
eval{ $doc->add_stylesheet( foo => 'xsl_style.xsl') };
matches( $@, q{^unsupported style sheet type 'foo'}, 'unsupported stylesheet type');
}
{ # creating a CDATA element
my $elt1= XML::Twig::Elt->new( foo => { '#CDATA' => 1 }, '<&>');
is( $elt1->sprint, ']]> ', "creating a CDATA element");
my $elt2= XML::Twig::Elt->new( foo => { '#CDATA' => 1, att => 'v1' }, '<&>');
is( $elt2->sprint, ']]> ', "creating a CDATA element");
eval { my $elt3= XML::Twig::Elt->new( foo => { '#CDATA' => 1 }, "bar", $elt1); };
matches( $@, qr/^element #CDATA can only be created from text/,
"error in creating CDATA element");
my $elt4= XML::Twig::Elt->new( foo => { '#CDATA' => 1 }, '<&>', 'bar');
is( $elt4->sprint, 'bar]]> ', "creating a CDATA element (from list)");
}
{ # errors creating text/comment/pi elements
eval { my $elt= XML::Twig::Elt->new( '#PCDATA', []); };
matches( $@, qr/^element #PCDATA can only be created from text/, "error in creating PCDATA element");
eval { my $elt= XML::Twig::Elt->new( '#COMMENT', "foo", []); };
matches( $@, qr/^element #COMMENT can only be created from text/, "error in creating COMMENT element");
eval { my $elt= XML::Twig::Elt->new( '#PI', "foo", [], "bah!"); };
matches( $@, qr/^element #PI can only be created from text/, "error in creating PI element");
}
{ # set_cdata on non CDATA element
my $elt = XML::Twig::Elt->new("qux");
$elt->set_cdata("test this '<' & this '>'");
is( $elt->sprint, q{']]> }, "set_cdata on non CDATA element");
}
{ # set_comment on non comment element
my $elt = XML::Twig::Elt->new(qux => "toto");
$elt->set_comment( " booh ");
is( $elt->sprint, q{}, "set_comment on non comment element");
}
{ # set_pi on non pi element
my $elt = XML::Twig::Elt->new(qux => "toto");
$elt->set_pi( ta => "tie ramisu");
is( $elt->sprint, q{}, "set_pi on non pi element");
}
XML-Twig-3.50/t/test_need_3_args_open.t 0000755 0001750 0001750 00000002342 12346001775 020145 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
use XML::Twig;
# abort (before compiling so the 3 arg open doesn't cause a crash) unless perl 5.8+
BEGIN
{ if( $] < 5.008) { print "1..1\nok 1\n"; warn "skipping tests that require 3 args open\n"; exit 0; } }
my $TMAX=4;
print "1..$TMAX\n";
{ my $out='';
open( my $fh, '>', \$out);
my $doc=q{foo bar };
my $t= XML::Twig->new( twig_handlers => { elt => sub { $_->flush( $fh) } });
$t->parse( $doc);
is( $out, $doc, "flush to a scalar (with autoflush)");
$t->flush( $fh);
is( $out, $doc, "double flush");
$t->flush();
is( $out, $doc, "triple flush");
}
{
my $out= '';
my $twig = XML::Twig->new( output_encoding => 'utf-8',);
$twig->parse( " ");
my $greet = $twig->root->insert_new_elt( last_child => 'g');
$greet->set_text("Gr\x{00FC}\x{00DF}");
open(my $fh, '>:utf8', \$out);
$twig->print(\*$fh);
print {*$fh} "Copyright \x{00A9} 2008 Me ";
close($fh);
is( $out, qq{Grüß Copyright © 2008 Me },
'$t->print and regular print mixed, with utf-8 encoding'
);
}
XML-Twig-3.50/t/test_new_features_3_16.t 0000755 0001750 0001750 00000015765 12346001775 020207 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
use XML::Twig;
my $TMAX=85;
my $DEBUG=0;
print "1..$TMAX\n";
# state information are now attached to each twig
# default/fixed attribute values are now filled when the "load_DTD" option is used
my $dtd_file= 'test_default_att.dtd';
my $dtd=<<'DTD';
DTD
my $doc = q{ };
my $filled_doc = q{}
.q{ }
.q{ }
.q{ }
.q{ }
.q{ };
{
open( FHDTD, ">$dtd_file") or die "cannot open dtd file '$dtd': $!";
print FHDTD $dtd;
close FHDTD;
my $doc_with_external_dtd= qq{$doc};
my $result= XML::Twig->new( error_context => 1, load_DTD => 1)
->parse( $doc_with_external_dtd)
->root->sprint;
is( $result => $filled_doc, 'filling attribute default values with EXTERNAL DTD');
unlink $dtd_file;
}
{
my $doc_with_internal_dtd= qq{$doc};
my $result= XML::Twig->new( error_context => 1, load_DTD => 1)
->parse( $doc_with_internal_dtd)
->root->sprint;
is( $result => $filled_doc, 'filling attribute default values with INTERNAL DTD');
}
# test the first_descendant method
{
my $t= XML::Twig->new->parse( ' ');
is( $t->root->first_child->first_descendant( 'a')->tag, 'a', 'first_descendant succeeds');
nok( $t->root->first_child->first_descendant( 'b'), 'first_descendant fails (match outside of the subtree)');
}
# test the index option and method
{ my $doc=q{t1 t2 };
my $t= XML::Twig->new( index => [ 't', 'none' ])->parse( $doc);
is( $t->index( 't', 0)->text, 't1', 'index');
is( $t->index( 't', 1)->text, 't2', 'index');
is_undef( $t->index( 't', 2), 'index');
is( $t->index( 't', -1)->text, 't2', 'index');
my $index= $t->index( 't');
is( $index->[0]->text, 't1', 'index');
is( $index->[ 1]->text, 't2', 'index');
is_undef( $index->[ 2], 'index');
is( $index->[-1]->text, 't2', 'index');
}
{ my $doc=q{t1 t2 };
my $t= XML::Twig->new( index => { target => 't' })->parse( $doc);
is( $t->index( 'target', 0)->text, 't1', 'index');
is( $t->index( 'target', 1)->text, 't2', 'index');
is_undef( $t->index( 'target', 2), 'index');
is( $t->index( 'target', -1)->text, 't2', 'index');
my $index= $t->index( 'target');
is( $index->[0]->text, 't1', 'index');
is( $index->[ 1]->text, 't2', 'index');
is_undef( $index->[ 2], 'index');
is( $index->[-1]->text, 't2', 'index');
}
# test the remove_cdata option
{ my $doc = q{]]> };
my $escaped_doc= q{<tag&> };
my $t= XML::Twig->new( remove_cdata => 1)->parse( $doc);
is( $t->sprint, $escaped_doc, 'remove_cdata on');
$t= XML::Twig->new( remove_cdata => 0)->parse( $doc);
is( $t->sprint, $doc, 'remove_cdata off');
}
# test the create_accessors method
if( $] < 5.006)
{ skip( 11 => "create_accessors not tested with perl < 5.006"); }
else
{ my $doc= ' ';
my $t= XML::Twig->new->parse( $doc);
$t->create_accessors( qw(att1 att2));
my $root= $t->root;
is( $root->att1, 1, 'attribute getter');
$root->att1( 2);
is( $root->att1, 2, 'attribute setter');
eval '$root->att1=3'; # eval'ed to keep 5.005 from barfing
is( $root->att1, 3, 'attribute as lvalue');
eval '$root->att1++'; # eval'ed to keep 5.005 from barfing
is( $root->att1, 4, 'attribute as lvalue (++)');
is( $root->att1, $root->att( 'att1'), 'check with regular att method');
eval { $^W=0; $root->att3; $^W=1; };
matches( $@, q{^Can't locate object method "att3" via package "XML::Twig::Elt" }, 'unknow accessor');
is( $root->att2, undef, 'get non-existent att');
$root->att2( 'bar');
is( $root->att2, "bar", 'get non-existent att');
is( $t->sprint, ' ', 'final output');
eval { $t->create_accessors( 'tag'); };
matches( $@, q{^attempt to redefine existing method tag using att_accessors }, 'duplicate accessor');
$@='';
eval { XML::Twig->create_accessors( 'att2'); };
is( $@, '', 'redefining existing accessor');
}
{ # test embedded comments/pis
foreach my $doc (
q{text },
q{textmore },
q{textmore },
q{textmoremore2 },
q{moremore2 },
q{ },
q{tatatoto },
q{tata <toto < },
q{textmore & even moremore2 },
q{text },
q{ more more2 },
q{ more more2 },
)
{ my $t= XML::Twig->new->parse( $doc);
is( $t->sprint, $doc, "comment within pcdata ($doc)");
my $t2= XML::Twig->new( keep_encoding => 1)->parse( $doc);
is( $t2->sprint, $doc, "comment within pcdata in keep encoding mode($doc)");
my $doc_pi= $doc;
$doc_pi=~ s{}{?>}g;
my $t3= XML::Twig->new->parse( $doc_pi);
is( $t3->sprint, $doc_pi, "pi within pcdata ($doc_pi)");
my $t4= XML::Twig->new( keep_encoding => 1)->parse( $doc_pi);
is( $t4->sprint, $doc_pi, "pi within pcdata in keep encoding mode($doc_pi)");
}
}
{ # test processing of embedded comments/pis
my $doc= q{foobar foobar };
my $t= XML::Twig->new->parse( $doc);
my @elt= $t->findnodes( '//elt[string()="foobar"]');
is( scalar( @elt), 2, 'searching on text with embedded comments');
foreach my $elt (@elt) { $elt->set_text( 'toto'); }
is( $t->sprint, q{toto toto }, "set_text");
my $t2= XML::Twig->new( keep_encoding => 1)->parse( $doc);
@elt= $t2->findnodes( '//elt[string()="foobar"]');
is( scalar( @elt), 2, 'searching on text with embedded comments');
foreach my $elt (@elt) { $elt->set_text( 'toto'); }
is( $t2->sprint, q{toto toto }, "set_text");
}
XML-Twig-3.50/t/test_bugs_3_22.t 0000755 0001750 0001750 00000051703 12346001774 016444 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
my $DEBUG=0;
use lib File::Spec->catdir(File::Spec->curdir,"blib/lib");
use XML::Twig;
my $TMAX=181;
print "1..$TMAX\n";
{ # testing how well embedded comments and pi's are kept when changing the content
my @tests= ( [ "foo bar baz", "foo bar", "foo bar" ],
[ "foo bar baz", "foo bar baz foobar", "foo bar baz foobar" ],
[ "foo bar foobar tutu", "bar tutu", "bar tutu" ],
[ "foo bar foobar baz", "foobar baz", "foobar baz"],
[ "foo baz", "foo bar baz", "foo bar baz"],
[ "foo baz", "foo bar baz", "foo bar baz"],
[ "foo bar baz", "bar baz", "bar baz"],
[ "foo bar baz toto", "foo toto", "foo toto"],
);
foreach my $test (@tests)
{ my( $initial, $set, $expected)= @$test;
my $t= XML::Twig->nparse( "$initial ");
$t->root->set_content( $set);
is( $t->sprint, "$expected ", "set_content '$initial' => '$set'");
}
}
{ # RT #17145
my $twig= new XML::Twig()->parse(" ");
is( scalar( $twig->get_xpath('//root/elt[1]/child')), 0, "Context position of non-existent elements in XPATH expressions");
}
{ # some extra coverage
my @siblings= XML::Twig->nparse( " ")->root->following_elts;
is( scalar( @siblings), 0, "following_elts on last sibling");
is( XML::Twig->nparse( " ")->root->del_id->sprint, " ", "del_id on elt with no atts");
# next_elt with deep tree (
my $t= XML::Twig->nparse( q{
});
foreach my $e ($t->root->descendants_or_self)
{ is( scalar( $e->_descendants), $e->att( 'n'), "_descendant " . $e->tag . "\n");
is( scalar( $e->_descendants( 1)), $e->att( 'n') + 1, "_descendant(1) " . $e->tag . "\n");
}
}
{
my $exp= '/foo/1^%';
eval { XML::Twig->nparse( " ")->get_xpath( $exp); };
matches( $@, "^error in xpath expression", "xpath with valid expression then stuff left");
}
{
my $t = XML::Twig->nparse( " ");
my $root = $t->root;
my $elt =XML::Twig::Elt->new( 'foo');
foreach my $pos ( qw( before after))
{ eval { $elt->paste( $pos => $root); };
matches( $@, "^cannot paste $pos root", "paste $pos root");
eval " \$elt->paste_$pos( \$root)";
matches( $@, "^cannot paste $pos root", "paste $pos root");
}
}
{ is( XML::Twig->nparse( comments => "process", pi => "process", " ")->_dump,
"document\n|-doc\n| |-COMMENT: ''\n| |-PI: 't' - 'data'\n| |-PI: 't' - ''\n",
"_dump PI/comment"
);
}
{ is( XML::Twig->nparse( ' ')->root->get_xpath( '.', 0)->gi, 'doc', 'get_xpath: .'); }
{ my $t= XML::Twig->nparse( ' ');
$t->first_elt( '#CDATA')->set_text( 'bar');
is( $t->sprint, ' ', " set_text on CDATA");
$t->root->set_text( 'bar');
is( $t->sprint, 'bar ', " set_text on elt containing CDATA");
$t= XML::Twig->nparse( ' ');
$t->first_elt( '#CDATA')->set_text( 'bar', force_pcdata => 1);
is( $t->sprint, 'bar ', " set_text on CDATA with force_pcdata");}
# print/flush entity
# SAX export entity
{ my $enc= "a_non_existent_encoding_bwaaahhh";
eval { XML::Twig->iconv_convert( $enc); };
matches( $@, "^(Unsupported|Text::Iconv not available|Can't locate)", "unsupported encoding");
}
{ # test comments handlers
my $doc= qq{ };
is( XML::Twig->nparse( twig_handlers => { '#COMMENT' => sub { return uc( $_[1]); } }, $doc)->sprint,
qq{ },
"comment handler"
);
is( XML::Twig->nparse( twig_handlers => { '#COMMENT' => sub { return uc( $_[1]); } }, keep_encoding => 1, $doc)->sprint,
qq{ },
"comment handler (with keep_encoding)"
);
is( XML::Twig->nparse( twig_handlers => { '#COMMENT' => sub { return; } }, keep_encoding => 0, $doc)->sprint,
qq{ },
"comment handler returning undef comment"
);
is( XML::Twig->nparse( twig_handlers => { '#COMMENT' => sub { return ''; } }, keep_encoding => 1, $doc)->sprint,
qq{ },
"comment handler returning empty comment (with keep_encoding)"
);
is( XML::Twig->nparse( comments => 'process', twig_handlers => { '#COMMENT' => sub { $_->set_comment( uc( $_->comment)); } },
keep_encoding => 0, $doc)->sprint,
qq{ },
"comment handler, process mode"
);
is( XML::Twig->nparse( comments => 'process', twig_handlers => { '#COMMENT' => sub { $_->set_comment( uc( $_->comment)); } },
keep_encoding => 1, $doc)->sprint,
qq{ },
"comment handler (with keep_encoding), process mode"
);
is( XML::Twig->nparse( comments => 'process', twig_handlers => { elt => sub { $_->cut; } }, keep_encoding => 0, $doc)->sprint,
qq{ },
"comment handler deletes comment, process mode"
);
is( XML::Twig->nparse( comments => 'process', twig_handlers => { '#COMMENT' => sub { $_->cut; } }, keep_encoding => 0, $doc)->sprint,
qq{ },
"comment handler deletes comment, process mode"
);
is( XML::Twig->nparse( comments => 'process', twig_handlers => { '#COMMENT' => sub { $_->set_comment( ''); } }, keep_encoding => 1, $doc)->sprint,
qq{ },
"comment handler returning empty comment (with keep_encoding), process mode"
);
}
{ # check pi element handler in keep_encoding mode
is( XML::Twig->nparse( pi => 'process', twig_handlers => { '?t' => sub { $_->set_data( uc( $_->data)); } }, ' ')->sprint,
' ', 'pi element handler');
is( XML::Twig->nparse( pi => 'process', keep_encoding => 1,twig_handlers => { '?t' => sub { $_->set_data( uc( $_->data)); } },
' ')->sprint,
' ', 'pi element handler in keep_encoding mode');
}
{ # test changes on comments before the root element
my $doc= q{ };
is( XML::Twig->nparse( $doc)->sprint, $doc, 'comment after root element');
is_like( XML::Twig->nparse( pi => 'process', comments => 'process', $doc)->sprint, $doc, 'comment before root element (pi/comment => process)');
is_like( XML::Twig->nparse( pi => 'process', $doc)->sprint, $doc, 'comment before root element (pi => process)');
is_like( XML::Twig->nparse( comments => 'process', $doc)->sprint, $doc, 'comment before root element (comment => process)');
}
{ # test bug on comments after the root element RT #17064
my $doc= q{ };
is( XML::Twig->nparse( $doc)->sprint, $doc, 'comment after root element');
is( XML::Twig->nparse( pi => 'process', comments => 'process', $doc)->sprint, $doc, 'comment after root element (pi/comment => process)');
is_like( XML::Twig->nparse( pi => 'process', $doc)->sprint, $doc, 'comment before root element (pi => process)');
is_like( XML::Twig->nparse( comments => 'process', $doc)->sprint, $doc, 'comment before root element (comment => process)');
}
{ # test bug on doctype declaration (RT #17044)
my $doc= qq{\n };
is( XML::Twig->nparse( $doc)->sprint, $doc, "doctype with public id");
is( XML::Twig->nparse( $doc)->sprint( Update_DTD => 1), $doc, "doctype with public id (update_DTD => 1)");
$doc= qq{\n };
is( XML::Twig->nparse( $doc)->sprint, $doc, "doctype with public id");
is( XML::Twig->nparse( $doc)->sprint( updateDTD => 1) , $doc, "doctype with public id (update_DTD => 1)");
}
{ # test bug on tag names similar to internal names RT #16540
ok( XML::Twig->nparse( twig_handlers => { level => sub {} }, ' '), " bug on tag names similar to internal names RT #16540");
}
{ # test parsing of an html string
if( XML::Twig::_use( 'HTML::TreeBuilder', 3.13) && XML::Twig::_use( 'HTML::Entities::Numbered'))
{
ok( XML::Twig->parse( error_context => 1, '
foo
bar
été
'), "parsing an html string");
}
else
{ skip( 1, "need HTML::TreeBuilder 3.13+ and HTML::Entities::Numbered for this test"); }
}
{ # testing print_to_file
my $tmp= "print_to_file.xml";
my $doc= "foo ";
unlink( $tmp); # no check, it could not be there
my $t1= XML::Twig->nparse( $doc)->print_to_file( $tmp);
ok( -f $tmp, "print_to_file created document");
my $t2= XML::Twig->nparse( $tmp);
is( $t2->sprint, $t1->sprint, "generated document identical to original document");
unlink( $tmp);
my $e1= XML::Twig->parse( 'foo bar ')->first_elt( 'b')->print_to_file( $tmp);
ok( -f $tmp, "print_to_file on elt created document");
$t2= XML::Twig->nparse( $tmp);
is( $t2->sprint, 'bar ', "generated sub-document identical to original sub-document");
unlink( $tmp);
# failure modes
eval { XML::Twig->nparse( $tmp); };
mtest( $@, "Couldn't open $tmp:");
my $non_existent="non_existent_I_hope_01/tmp";
while( -f $non_existent) { $non_existent++; } # most likely unnecessary ;--)
eval { $t1->print_to_file( $non_existent); };
mtest( $@, "cannot create file $non_existent:");
}
{
my $doc=q{ };
my $t= XML::Twig->nparse( $doc);
test_get_xpath( $t, q{/doc/elt[1][@att2="v2"]}, '');
}
{ my $doc=q{foo bar baz foobar };
my $t= XML::Twig->nparse( $doc);
test_get_xpath( $t, q{/d/e[@a="1"][2]}, 'e2');
test_get_xpath( $t, q{/d/e[@a="1"][-2]}, 'e2');
test_get_xpath( $t, q{/d/e[@a="1"][-1]}, 'e4');
test_get_xpath( $t, q{/d/e[@a="1"][-3]}, 'e1');
}
{ # test support for new conditions condition in get_xpath
my $doc=q{foo bar baz };
my $t= XML::Twig->nparse( $doc);
# just checking
test_get_xpath( $t, q{//elt[@a]}, 'elt1');
is( ids( $t->get_xpath( q{//*[@a]})), 'd1:elt1', '//*[@a] xpath exp');
# test support for !@att condition in get_xpath
is( ids( $t->get_xpath( q{//elt[!@a]})), 'elt2:elt3', '//elt[!@a] xpath exp');
is( ids( $t->get_xpath( q{//elt[not@a]})), 'elt2:elt3', '//elt[not@a] xpath exp');
is( ids( $t->get_xpath( q{/doc/elt[not@a]})), 'elt2:elt3', '/doc/elt[not@a] xpath exp');
is( ids( $t->get_xpath( q{//*[!@a]})), 'elt2:elt3', '//*[!@a] xpath exp');
is( ids( $t->get_xpath( q{//*[not @a]})), 'elt2:elt3', '//*[not @a] xpath exp');
is( ids( $t->get_xpath( q{/doc/*[not @a]})), 'elt2:elt3', '/doc/*[not @a] xpath exp');
# support for ( and )
test_get_xpath( $t, q{//*[@id="d1" or @a and @id="elt1"]}, 'd1:elt1');
test_get_xpath( $t, q{//*[(@id="d1" or @a) and @id="elt1"]}, 'elt1');
}
{ # more test on new XPath support: axis in node test part
my $doc=q{
};
my $t= XML::Twig->nparse( $doc);
# parent axis in node test part
test_get_xpath( $t, q{/doc//selt/..}, 'elt1:elta1');
test_get_xpath( $t, q{/doc//selt/parent::elt}, 'elt1');
test_get_xpath( $t, q{/doc//selt/parent::elta}, 'elta1');
test_get_xpath( $t, q{//sseltb/ancestor::eltc}, 'eltc1');
test_get_xpath( $t, q{//sseltb/ancestor::*}, 'd1:eltb1:seltb1:eltc1:seltb2');
test_get_xpath( $t, q{//sseltb/ancestor-or-self::eltc}, 'eltc1');
test_get_xpath( $t, q{//sseltb/ancestor-or-self::*}, 'd1:eltb1:seltb1:sseltb1:eltc1:seltb2:sseltb2');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant::*}, 'seltb2:sseltb2');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant::sseltb}, 'sseltb2');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant::eltc}, '');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant-or-self::*}, 'eltc1:seltb2:sseltb2');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant-or-self::eltc}, 'eltc1');
test_get_xpath( $t, q{/doc//*[@id="eltc1"]/descendant-or-self::seltb}, 'seltb2');
test_get_xpath( $t, q{/doc/elt/following-sibling::*}, 'elta1:elt2:eltb1:eltc1');
test_get_xpath( $t, q{/doc/elt/preceding-sibling::*}, 'elt1:elta1');
test_get_xpath( $t, q{/doc/elt[@id="elt1"]/preceding-sibling::*}, '');
test_get_xpath( $t, q{/doc/elt/following-sibling::elt}, 'elt2');
test_get_xpath( $t, q{/doc/elt/preceding-sibling::elt}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@id="elt1"]/preceding-sibling::elt}, '');
is( $t->elt_id( "sseltb1")->following_elt->id, 'eltc1', 'following_elt');
is( ids( $t->elt_id( "sseltb1")->following_elts), 'eltc1:seltb2:sseltb2', 'following_elts');
is( ids( $t->elt_id( "sseltb1")->following_elts( '')), 'eltc1:seltb2:sseltb2', 'following_elts( "")');
my @elts= $t->elt_id( "eltc1")->descendants_or_self;
is( ids( @elts), 'eltc1:seltb2:sseltb2', 'descendants_or_self');
is( ids( XML::Twig::_unique_elts( @elts)), 'eltc1:seltb2:sseltb2', '_unique_elts');
test_get_xpath( $t, q{/doc//[@id="sseltb1"]/following::*}, 'eltc1:seltb2:sseltb2');
test_get_xpath( $t, q{/doc//[@id="sseltb1"]/following::seltb}, 'seltb2');
test_get_xpath( $t, q{/doc//[@id="selt1"]/following::elt}, 'elt2');
ok( $t->root->last_descendant( 'doc'), "checking if last_descendant returns the element itself");
test_get_xpath( $t, q{/doc/preceding::*}, '');
test_get_xpath( $t, q{/doc/elt[1]/preceding::*}, '');
test_get_xpath( $t, q{/doc/elt/preceding::*}, 'd1:elt1:selt1:elta1:selt2');
test_get_xpath( $t, q{/doc//[@id="sseltb2"]/preceding::seltb}, 'seltb1');
test_get_xpath( $t, q{/doc//[@id="selt1"]/preceding::elt}, '');
test_get_xpath( $t, q{/doc//[@id="selt2"]/preceding::elt}, 'elt1');
test_get_xpath( $t, q{/doc/self::doc}, 'd1');
test_get_xpath( $t, q{/doc/self::*}, 'd1');
test_get_xpath( $t, q{/doc/self::elt}, '');
test_get_xpath( $t, q{//[@id="selt1"]/self::*}, 'selt1');
test_get_xpath( $t, q{//[@id="selt1"]/self::selt}, 'selt1');
test_get_xpath( $t, q{//[@id="selt1"]/self::elt}, '');
}
{ # more tests: more than 1 predicate
my $doc=q{ };
my $t= XML::Twig->nparse( $doc);
test_get_xpath( $t, q{/doc/elt[@id][@att="v1"]}, 'elt1:elt2');
test_get_xpath( $t, q{/doc/elt[@id][@att2="v1"]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@id][1]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@att="v1"][1]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@att="v2"][1]}, '');
test_get_xpath( $t, q{/doc/elt[@att="v1"][2]}, 'elt2');
test_get_xpath( $t, q{/doc/elt[1][@att2="v1"]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[1][@att2="v2"]}, '');
test_get_xpath( $t, q{/doc/elt[@att2="v2"][1]}, 'elt2');
test_get_xpath( $t, q{/doc/elt[@att2="v2"][2]}, '');
test_get_xpath( $t, q{/doc/elt[@att2][1]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@att2][2]}, 'elt2');
test_get_xpath( $t, q{/doc/elt[@att2][3]}, '');
test_get_xpath( $t, q{/doc/elt[@att2][-1]}, 'elt2');
test_get_xpath( $t, q{/doc/elt[@att2][-2]}, 'elt1');
test_get_xpath( $t, q{/doc/elt[@att2][-3]}, '');
}
{ # testing creation of elements in the proper class
package foo; use base 'XML::Twig::Elt'; package main;
my $t= XML::Twig->new( elt_class => "foo")->parse( ' ');
my $elt= $t->first_elt( 'elt');
$elt->set_text( 'bar');
is( $elt->first_child->text, 'bar', "content of element created with set_text");
is( ref( $elt->first_child), 'foo', "class of element created with set_text");
$elt->set_content( 'baz');
is( $elt->first_child->text, 'baz', "content of element created with set_content");
is( ref( $elt->first_child), 'foo', "class of element created with set_content");
$elt->insert( 'toto');
is( $elt->first_child->tag, 'toto', "tag of element created with set_content");
is( ref( $elt->first_child), 'foo', "class of element created with insert");
$elt->insert_new_elt( first_child => 'tata');
is( $elt->first_child->tag, 'tata', "tag of element created with insert_new_elt");
is( ref( $elt->first_child), 'foo', "class of element created with insert");
$elt->wrap_in( 'tutu');
is( $t->root->first_child->tag, 'tutu', "tag of element created with wrap_in");
is( ref( $t->root->first_child), 'foo', "class of element created with wrap_in");
$elt->prefix( 'titi');
is( $elt->first_child->text, 'titi', "content of element created with prefix");
is( ref( $elt->first_child), 'foo', "class of element created with prefix");
$elt->suffix( 'foobar');
is( $elt->last_child->text, 'foobar', "content of element created with suffix");
is( ref( $elt->last_child), 'foo', "class of element created with suffix");
$elt->last_child->split_at( 3);
is( $elt->last_child->text, 'bar', "content of element created with split_at");
is( ref( $elt->last_child), 'foo', "class of element created with split_at");
is( ref( $elt->copy), 'foo', "class of element created with copy");
$t= XML::Twig->new( elt_class => "foo")->parse( 'toto ');
$t->root->subs_text( qr{(to)} => '&elt( p => $1)');
is( $t->sprint, 'to
to
', "subs_text result");
my $result= join( '-', map { join( ":", ref($_), $_->tag) } $t->root->descendants);
is( $result, "foo:p-foo:#PCDATA-foo:p-foo:#PCDATA", "subs_text classes and tags");
}
{ # wrap children with > in attribute
my $doc=q{ };
my $result =XML::Twig->new->parse( $doc)->root->wrap_children( '+', "w")->strip_att( 'id')->sprint;
my $expected = q{ };
is( $result => $expected, "wrap_children with > in attributes");
$result =XML::Twig->new->parse( $doc)->root->wrap_children( '+', "w")->strip_att( 'id')->sprint;
$expected = q{ };
is( $result => $expected, "wrap_children with > in attributes, > in condition");
$result =XML::Twig->new->parse( $doc)->root->wrap_children( '+', "w")->strip_att( 'id')->sprint;
$expected = q{ };
is( $result => $expected, "wrap_children with > in attributes un-escaped > in condition");
$result =XML::Twig->new->parse( $doc)->root->wrap_children( '+', "w")->strip_att( 'id')->sprint;
$expected = q{ };
is( $result => $expected, "wrap_children with > in attributes, 2 atts in condition");
$result =XML::Twig->new->parse( $doc)->root->wrap_children( '+', "w")->strip_att( 'id')->sprint;
$expected = q{ };
is( $result => $expected, "wrap_children with > in attributes, 2 atts in condition (no child matches)");
}
{ # test improvements to wrap_children
my $doc= q{ok NOK };
my $expected= q{ok NOK };
my $t= XML::Twig->new->parse( $doc);
$t->root->wrap_children( '+', w => { a => "&" });
$t->root->strip_att( 'id');
is( $t->sprint, $expected, "wrap_children with &");
}
{ # test bug on tests on attributes with a value of 0 (RT #15671)
my $t= XML::Twig->nparse( ' ');
my $root = $t->root();
is( scalar $root->children('*[@id="1"]'), 1, 'testing @att="1"');
is( scalar $root->children('*[@id="0"]'), 1, 'testing @att="0"');
is( scalar $root->children('*[@id="0" or @id="1"]'), 2, 'testing @att="0" or');
is( scalar $root->children('*[@id="0" and @id="1"]'), 0, 'testing @att="0" and');
}
{ # test that the '>' after the doctype is properly output when there is no DTD RT#
my $doctype='';
my $doc="$doctype ";
is_like( XML::Twig->nparse( $doc)->sprint, $doc);
is_like( XML::Twig->nparse( $doc)->doctype, $doctype);
}
XML-Twig-3.50/t/test_nav.t 0000755 0001750 0001750 00000010706 12346001774 015541 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
# test for the various conditions in navigation methods
use XML::Twig;
my $t= XML::Twig->new;
$t->parse(
'
text1
text
text
text}
text"
text\'
text 2
text level1
');
my $root= $t->root;
my @data= grep { !/^##/ && m{\S} } ;
my %result= map { chomp; split /\s*=>\s*/} @data;
my $nb_tests= keys %result;
print "1..$nb_tests\n";
foreach my $cond ( sort keys %result)
{ my $expected_result= $result{$cond};
my $result;
my $res= $root->first_child( $cond);
if( $res)
{ if( $res->id) { $result= $res->id; }
else { $result= $res->text;
$result=~ s/^\s+//;
$result=~ s/\s+$//;
}
}
else { $result= 'none'; }
is( $result => $expected_result, "$cond");
}
exit 0;
__DATA__
=> elt-1
elt => elt-1
#ELT => elt-1
!#ELT => text level1
#TEXT => text level1
!#TEXT => elt-1
elt2 => elt2-1
foo => none
elt[@id] => elt-1
elt[@id!="elt-1"] => elt-2
elt[@duh!="elt-1"] => elt-1
elt[@toto] => elt-1
elt[!@toto] => elt-2
/2$/ => elt2-1
elt[@id="elt-1"] => elt-1
elt[@id="elt-1" or @foo="bar"] => elt-1
elt[@id="elt-1" and @foo!="bar"] => elt-1
elt[@id="elt-1" and @foo="bar"] => none
elt2[@id=~/elt2/] => elt2-1
elt[@id="elt2-1"] => none
elt2[@id="elt2-1"] => elt2-1
elt[@id=~/elt2/] => none
*[@id="elt1-1"] => none
*[@foo] => none
*[@id] => elt-1
*[@id="elt-1" or @foo="bar"] => elt-1
*[@id=~/elt2$/] => none
*[@id=~/2-2$/] => elt2-2
*[@id=~/^elt2/] => elt2-1
[@id="elt1-1"] => none
[@foo] => none
[@id] => elt-1
[@id="elt-1" or @foo="bar"] => elt-1
[@id=~/elt2$/] => none
[@id=~/2-2$/] => elt2-2
[@id=~/^elt2/] => elt2-1
#PCDATA => text level1
elt[text(subelt)="text}" ] => none
elt2[text(subelt)="text}"] => elt2-3
elt2[text()="text}"] => none
elt2[text(subelt)='text"'] => elt2-3
elt2[text(subelt)="text'"] => elt2-3
[text(subelt)="text}"] => elt2-3
[text(subelt)="text1"] => elt-1
[text(subelt)="text 2"] => elt2-3
*[text(subelt)="text1"] => elt-1
*[text(subelt)="text 2"] => elt2-3
elt2[text(subelt)="text 2"]=> elt2-3
elt[text(subelt)="text 2"] => none
*[text(subelt)="foo"] => none
*[text(subelt)=~/text/] => elt-1
*[text(subelt)=~/^ext/] => none
[text(subelt)="foo"] => none
[text(subelt)=~/text/] => elt-1
[text(subelt)=~/^ext/] => none
elt2[text(subelt)="text"] => elt2-2
elt[text(subelt)="text"] => none
elt[text(subelt)="foo"] => none
elt[text(subelt)=~/text/] => elt-1
elt[text(subelt)=~/^ext/] => none
elt2[text(subelt)="text"] => elt2-3
elt2[text(subelt)="foo"] => none
elt2[text(subelt)=~/tex/] => elt2-3
elt2[text(subelt)=~/^et/] => none
elt2[text(subelt)=~/^et}/] => none
/ELT/i => elt-1
elt2[text(subelt)='text"'] => elt2-3
elt[@val>'1'] => elt-2
@val>"1" => elt-2
elt[@val<"2"] => elt-1
@val<"2" => elt-1
elt[@val>1] => elt-2
@val>1 => elt-2
elt[@val<2] => elt-1
@val<2 => elt-1
@val => elt-1
[@val="1" or @dummy="2"] => elt-1
[@val="2" or @dummy="2"] => elt-2
*[@val="1" or @dummy="2"] => elt-1
*[@val="2" or @dummy="2"] => elt-2
@val="1" and @dummy="2" => none
@val="1" or @dummy="2" => elt-1
@val="2" or @dummy="2" => elt-2
[@val=~/2/] => elt-2
*[@val=~/2/] => elt-2
@val=~/^2/ => elt-2
@val!~/^1/ => elt-2
XML-Twig-3.50/t/xmlxpath_01basic.t 0000755 0001750 0001750 00000001026 12346001775 017061 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
use Test;
plan( tests => 5);
ok(1);
my $t= XML::Twig::XPath->new->parse( \*DATA);
ok($t);
my @root = $t->findnodes('/AAA');
ok(@root, 1);
my @ccc = $t->findnodes('/AAA/CCC');
ok(@ccc, 3);
my @bbb = $t->findnodes('/AAA/DDD/BBB');
ok(@bbb, 2);
exit 0;
__DATA__
Text
XML-Twig-3.50/t/test5.t 0000755 0001750 0001750 00000047320 12346001774 014764 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use XML::Twig;
$|=1;
my $doc= '
p2 (/doc/p1/p2)
p2 (/doc/p1/p3/p2)
p2 (/doc/p2)
p2 (/doc/p2)
p2 (/doc/p2)
p2 (/doc/p2)
p2 (/doc/p3/p2)
';
my $TMAX=80; # do not forget to update
print "1..$TMAX\n";
my $t= new XML::Twig;
$t->parse( $doc);
my $elt1= $t->elt_id( 'elt1');
my $elt2= $t->elt_id( 'elt2');
my $elt3= $t->elt_id( 'elt3');
my $root= $t->root;
# testing before and after
my $res= $elt1->before( $elt2);
if( $res) { print "ok 1\n"; } else { print "not ok 1\n"; }
$res= $elt2->before( $elt3);
if( $res) { print "ok 2\n"; } else { print "not ok 2\n"; }
$res= $elt1->before( $elt3);
if( $res) { print "ok 3\n"; } else { print "not ok 3\n"; }
$res= $elt3->before( $elt2);
unless( $res) { print "ok 4\n"; } else { print "not ok 4\n"; }
$res= $elt1->after( $elt2);
unless( $res) { print "ok 5\n"; } else { print "not ok 5\n"; }
$res= $elt1->after( $elt3);
unless( $res) { print "ok 6\n"; } else { print "not ok 6\n"; }
$res= $elt3->after( $elt2);
if( $res) { print "ok 7\n"; } else { print "not ok 7\n"; }
$res= $elt1->before( $root);
unless( $res) { print "ok 8\n"; } else { print "not ok 8\n"; }
$res= $root->before( $elt1);
if( $res) { print "ok 9\n"; } else { print "not ok 9\n"; }
# testing path capabilities
my $path= $elt1->path;
my $exp_path= '/doc/elt1/elt2';
if( $path eq $exp_path)
{ print "ok 10\n"; } else { print "not ok 10\n"; print "$path instead\n"; warn "of $exp_path\n"; }
$path= $elt2->path;
$exp_path= '/doc/elt1/elt2/elt3';
if( $path eq $exp_path)
{ print "ok 11\n"; } else { print "not ok 11\n"; warn "$path instead of $exp_path\n"; }
$path= $elt3->path;
$exp_path= '/doc/elt1/elt2';
if( $path eq $exp_path)
{ print "ok 12\n"; } else { print "not ok 12\n"; warn "$path instead of $exp_path\n"; }
$path= $root->path;
$exp_path= '/doc';
if( $path eq $exp_path)
{ print "ok 13\n"; } else { print "not ok 13\n"; warn "$path instead of $exp_path\n"; }
my $id1=''; my $exp_id1= 'p2_1';
my $id2=''; my $exp_id2= 'p2_3p2_4';
my $id3=''; my $exp_id3= 'p2_2p2_7';
my $id4=''; my $exp_id4= 'p2_5p2_6';
my $path_error='';
my $t2= new XML::Twig( TwigHandlers =>
{ '/doc/p1/p2' => sub { $id1.= $_[1]->id; return; },
'/doc/p2' => sub { $id2.= $_[1]->id; return; },
'p3/p2' => sub { $id3.= $_[1]->id; return; },
'p2' => sub { $id4.= $_[1]->id; return; },
_all_ => sub { my( $t, $elt)= @_;
my $gi= $elt->gi;
my $tpath= $t->path( $gi); my $epath= $elt->path;
unless( $tpath eq $epath)
{ $path_error.= " $tpath <> $epath\n"; }
}
}
);
$t2->parse( $doc);
if( $id1 eq $exp_id1)
{ print "ok 14\n"; } else { print "not ok 14\n"; warn "$id1 instead of $exp_id1\n"; }
if( $id2 eq $exp_id2)
{ print "ok 15\n"; } else { print "not ok 15\n"; warn "$id2 instead of $exp_id2\n"; }
if( $id3 eq $exp_id3)
{ print "ok 16\n"; } else { print "not ok 16\n"; warn "$id3 instead of $exp_id3\n"; }
if( $id4 eq $exp_id4)
{ print "ok 17\n"; } else { print "not ok 17\n"; warn "$id4 instead of $exp_id4\n"; }
unless( $path_error)
{ print "ok 18\n"; } else { print "not ok 18\n"; warn "$path_error\n"; }
$id1=''; $exp_id1= 'p2_1';
my $t3= new XML::Twig( TwigRoots => { '/doc/p1/p2' => sub { $id1.= $_[1]->id; } } );
$t3->parse( $doc);
if( $id1 eq $exp_id1)
{ print "ok 19\n"; } else { print "not ok 19\n"; warn "$id1 instead of $exp_id1\n"; }
$id2=''; $exp_id2= 'p2_3p2_4';
$t3= new XML::Twig( TwigRoots => { '/doc/p2' => sub { $id2.= $_[1]->id;} } );
$t3->parse( $doc);
if( $id2 eq $exp_id2)
{ print "ok 20\n"; } else { print "not ok 20\n"; warn "$id2 instead of $exp_id2\n"; }
$id3=''; $exp_id3= 'p2_2p2_7';
$t3= new XML::Twig( TwigRoots => { 'p3/p2' => sub { $id3.= $_[1]->id;} } );
$t3->parse( $doc);
if( $id3 eq $exp_id3)
{ print "ok 21\n"; } else { print "not ok 21\n"; warn "$id3 instead of $exp_id3\n"; }
# test what happens to 0 in pcdata/cdata
my $pcdata= '0 ';
my $cdata= ' ';
my $t4= new XML::Twig;
$t4->parse( $pcdata);
if( my $res= $t4->sprint eq $pcdata) { print "ok 22\n"; }
else { print "not ok 22\n"; warn "sprint returns $res instead of $pcdata\n"; }
$t4->parse( $pcdata);
if( my $res= $t4->root->text eq '0') { print "ok 23\n"; }
else { print "not ok 23\n"; warn "sprint returns $res instead of '0'\n"; }
$t4->parse( $cdata);
if( my $res= $t4->sprint eq $cdata) { print "ok 24\n"; }
else { print "not ok 23\n"; warn "sprint returns $res instead of $cdata\n"; }
$t4->parse( $cdata);
if( my $res= $t4->root->text eq '0') { print "ok 25\n"; }
else { print "not ok 25\n"; warn "sprint returns $res instead of '0'\n"; }
my $test_inherit=
'
';
my $t5= new XML::Twig;
$t5->parse( $test_inherit);
my $subelt= $t5->root->first_child->first_child;
if( my $att= $subelt->att( 'att1') eq "subelt1") { print "ok 26\n"; }
else { print "not ok 26\n"; warn "sprint returns $att instead of 'subelt1'\n"; }
if( my $att= $subelt->inherit_att( 'att1') eq "subelt1") { print "ok 27\n"; }
else { print "not ok 27\n"; warn "sprint returns $att instead of 'subelt1'\n"; }
if( my $att= $subelt->inherit_att( 'att1', 'elt') eq "elt1") { print "ok 28\n"; }
else { print "not ok 28 sprint returns $att instead of 'elt1'\n"; }
if( my $att= $subelt->inherit_att( 'att1', 'elt', 'doc') eq "elt1") { print "ok 29\n"; }
else { print "not ok 29\n"; warn "sprint returns $att instead of 'elt1'\n"; }
if( my $att= $subelt->inherit_att( 'att1', "doc") eq "doc1") { print "ok 30\n"; }
else { print "not ok 30\n"; warn "sprint returns $att instead of 'doc1'\n"; }
if( my $att= $subelt->inherit_att( 'att3') eq "doc3") { print "ok 31\n"; }
else { print "not ok 31\n"; warn "sprint returns $att instead of 'doc3'\n"; }
if( my $att= $subelt->inherit_att( 'att3') eq "doc3") { print "ok 32\n"; }
else { print "not ok 32\n"; warn "sprint returns $att instead of 'doc3'\n"; }
if( my $att= $subelt->inherit_att( 'att_null') == 0) { print "ok 33\n"; }
else { print "not ok 33\n"; warn "sprint returns $att instead of '0'\n"; }
# test attribute paths
my $test_att_path=
'
';
my $res1='';
my $t6= new XML::Twig
( TwigHandlers => #'' (or VIM messes up colors)
{ 'elt[@id="elt1"]' => sub { $res1.= $_[1]->id} }
);
$t6->parse( $test_att_path);
if( $res1 eq 'elt1') { print "ok 34\n"; }
else { print "not ok 34\n"; warn "returns $res1 instead of elt1\n"; }
$res1='';
my $res2='';
$t6= new XML::Twig
( TwigHandlers =>
{ 'elt[@id="elt1"]' => sub { $res1.= $_[1]->id},
'elt[@att="val1"]' => sub { $res2.= $_[1]->id} },
);
$t6->parse( $test_att_path);
if( $res1 eq 'elt1') { print "ok 35\n"; }
else { print "not ok 35\n"; warn "returns $res1 instead of 'elt1'\n"; }
if( $res2 eq 'elt1elt2') { print "ok 36\n"; }
else { print "not ok 36\n"; warn "returns $res2 instead of 'elt1elt2'\n"; }
my $doc_with_escaped_entities=
q{<apos>''<apos><"> };
my $exp_res1= q{<apos>''<apos><"> };
my $exp_res2= q{''<"> };
my $t7= new XML::Twig();
$t7->parse( $doc_with_escaped_entities);
$res= $t7->sprint;
if( $res eq $exp_res1) { print "ok 37\n"; }
else { print "not ok 37\n"; warn "returns \n$res instead of \n$exp_res1\n"; }
$t7= new XML::Twig( KeepEncoding => 1, NoExpand => 1);
$t7->parse( $doc_with_escaped_entities);
$res= $t7->sprint;
if( $res eq $doc_with_escaped_entities) { print "ok 38\n"; }
else { print "not ok 38\n"; warn "returns \n$res instead of \n$doc_with_escaped_entities\n"; }
# test extra options for new
my $elt= XML::Twig::Elt->new( 'p');
$res= $elt->sprint;
my $exp_res= '
';
if( $res eq $exp_res) { print "ok 39\n"; }
else { print "not ok 39\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', q{#EMPTY});
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 40\n"; }
else { print "not ok 40\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att => 'val'});
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 41\n"; }
else { print "not ok 41\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att => 'val'}, '#EMPTY');
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 42\n"; }
else { print "not ok 42\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1', att2=> 'val2'});
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 43\n"; }
else { print "not ok 43\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1', att2=>'val2'}, '#EMPTY');
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 44\n"; }
else { print "not onot ok 44\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', "content");
$res= $elt->sprint;
$exp_res= 'content
';
if( $res eq $exp_res) { print "ok 45\n"; }
else { print "not ok 45\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1'}, "content");
$res= $elt->sprint;
$exp_res= 'content
';
if( $res eq $exp_res) { print "ok 46\n"; }
else { print "not ok 46\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1', att2=>'val2'}, "content");
$res= $elt->sprint;
$exp_res= 'content
';
if( $res eq $exp_res) { print "ok 47\n"; }
else { print "not ok 47\n"; warn "returns $res instead of $exp_res\n"; }
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1'}, "content", " more content");
$res= $elt->sprint;
$exp_res= 'content more content
';
if( $res eq $exp_res) { print "ok 48\n"; }
else { print "not ok 48\n"; warn "returns $res instead of $exp_res\n"; }
my $sub1= XML::Twig::Elt->new( 'sub', '#EMPTY');
my $sub2= XML::Twig::Elt->new( 'sub', { att => 'val'}, '#EMPTY');
my $sub3= XML::Twig::Elt->new( 'sub', "sub3");
my $sub4= XML::Twig::Elt->new( 'sub', "sub4");
my $sub5= XML::Twig::Elt->new( 'sub', "sub5", $sub3, "sub5 again", $sub4);
$elt= XML::Twig::Elt->new( 'p', { att1 => 'val1'}, $sub1, $sub2, $sub5);
$res= $elt->sprint;
$exp_res= ' '.
'sub5sub3 sub5 againsub4
';
if( $res eq $exp_res) { print "ok 49\n"; }
else { print "not ok 49\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$elt->set_empty_tag_style( 'html');
$res= $elt->sprint;
$exp_res= ' '.
'sub5sub3 sub5 againsub4
';
if( $res eq $exp_res) { print "ok 50\n"; }
else { print "not ok 50\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$elt->set_empty_tag_style( 'expand');
$res= $elt->sprint;
$exp_res= ' '.
'sub5sub3 sub5 againsub4
';
if( $res eq $exp_res) { print "ok 51\n"; }
else { print "not ok 51\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$elt->set_empty_tag_style( 'normal');
$res= $elt->sprint;
$exp_res= ' '.
'sub5sub3 sub5 againsub4
';
if( $res eq $exp_res) { print "ok 52\n"; }
else { print "not ok 52\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
my $new_elt= parse XML::Twig::Elt( $res);
$res= $new_elt->sprint;
$exp_res= ' '.
'sub5sub3 sub5 againsub4
';
if( $res eq $exp_res) { print "ok 53\n"; }
else { print "not ok 53\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$doc='text1 root1 text 2 ';
$res='';
$exp_res= 'text1 ';
$t= new XML::Twig( TwigHandlers =>
{ 'elt[string()="text1"]' => \&display1,
'elt[@att="val1"]' => \&display1,
},
);
$t->parse( $doc);
sub display1 { $res .=$_[1]->sprint; return 0; }
if( $res eq $exp_res) { print "ok 54\n"; }
else { print "not ok 54\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$res='';
$exp_res= 'text1 ' x 2;
$t= new XML::Twig( TwigHandlers =>
{ 'elt[string()="text1"]' => \&display2,
'elt[@att="val1"]' => \&display2,
},
);
$t->parse( $doc);
sub display2 { $res .=$_[1]->sprint; }
if( $res eq $exp_res) { print "ok 55\n"; }
else { print "not ok 55\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$doc= ' ';
$t= new XML::Twig;
$t->parse( $doc);
$res= $t->first_elt->id;
$exp_res= 'doc1';
if( $res eq $exp_res) { print "ok 56\n"; }
else { print "not ok 56\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$res= $t->first_elt( 'doc')->id;
$exp_res= 'doc1';
if( $res eq $exp_res) { print "ok 57\n"; }
else { print "not ok 57\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$res= $t->first_elt( 'sub')->id;
$exp_res= 'sub1';
if( $res eq $exp_res) { print "ok 58\n"; }
else { print "not ok 58\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$sub1= $t->first_elt( 'sub');
$res= $sub1->next_elt( 'sub')->id;
$exp_res= 'sub2';
if( $res eq $exp_res) { print "ok 59\n"; }
else { print "not ok 59\n"; warn "returns \n$res\n instead of \n$exp_res\n"; }
$sub1= $t->first_elt( 'sub');
$res= $sub1->next_elt( $sub1, 'sub');
unless( defined $res) { print "ok 60\n"; }
else { print "not ok 60\n"; warn "should return undef, returned elt is " . $res->id; }
$sub1= $t->first_elt( 'sub');
$sub2= $sub1->next_elt( 'sub');
$res= $sub2->next_elt( 'sub');
unless( defined $res) { print "ok 61\n"; }
else { print "not ok 61\n"; warn "should return undef, returned elt is" . $res->id; }
# test : (for name spaces) in elements
$doc="p1 p
p2 ";
$res='';
$exp_res='p1p2';
$t= new XML::Twig( TwigHandlers => { 'ns:p' => sub { $res .= $_[1]->text; } });
$t->parse( $doc);
if( $res eq $exp_res) { print "ok 62\n"; }
else { print "not ok 62\n"; warn "should return $exp_res, returned $res"; }
$exp_res="p";
my $e_res= $t->get_xpath( '/doc/p', 0);
$res= $e_res->text;
if( $res eq $exp_res) { print "ok 63\n"; }
else { print "not ok 63\n"; warn "should return $exp_res, returned $res"; }
$exp_res='p1p2';
$res='';
foreach ($t->get_xpath( 'ns:p'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 64\n"; }
else { print "not ok 64\n"; warn "should return $exp_res, returned $res"; }
# test : (for name spaces) in attributes
$doc='p1 p
p3
p2 ';
$res='';
$exp_res='p1';
$t= new XML::Twig( TwigHandlers =>
{ 'ns:p[@ns:a="a1"]' => sub { $res .= $_[1]->text; } });
$t->parse( $doc);
if( $res eq $exp_res) { print "ok 65\n"; }
else { print "not ok 65\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p3';
foreach ($t->find_nodes( 'p[@a="a1"]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 66\n"; }
else { print "not ok 66\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1';
foreach ($t->find_nodes( 'ns:p[@ns:a="a1"]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 67\n"; }
else { print "not ok 67\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1p2';
foreach ($t->get_xpath( 'ns:p[@ns:a="a1" or @ns:a="a2"]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 68\n"; }
else { print "not ok 68\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p';
foreach ($t->get_xpath( 'p[@b="a1" or @ns:a="a1"]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 69\n"; }
else { print "not ok 69\n"; warn "should return $exp_res, returned $res"; }
$doc='p1
p2
p3
p4
';
$res='';
$exp_res='p2p4';
$t= new XML::Twig( twig_handlers =>
{ 'p[@a]' => sub { $res .= $_[1]->text; } });
$t->parse( $doc);
if( $res eq $exp_res) { print "ok 70\n"; }
else { print "not ok 70\n"; warn "should return $exp_res, returned $res"; }
$res='';
foreach ($t->get_xpath( '//p[@a]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 71\n"; }
else { print "not ok 71\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1p2p4';
foreach ($t->get_xpath( '//p[@ns:a or @a ]'))
{ $res .= $_->text; }
if( $res eq $exp_res) { print "ok 72\n"; }
else { print "not ok 72\n"; warn "should return $exp_res, returned $res"; }
$doc='p1
p2
p3
p4
';
$res='';
$exp_res='p1p2p4';
$t= new XML::Twig();
$t->parse( $doc);
$res .= $_->text foreach ($t->get_xpath( '//*[@a]'));
if( $res eq $exp_res) { print "ok 73\n"; }
else { print "not ok 73\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1p2';
$res .= $_->text foreach ($t->get_xpath( '*[@a="a1"]'));
if( $res eq $exp_res) { print "ok 74\n"; }
else { print "not ok 74\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1p2';
$res .= $_->text foreach ($t->get_xpath( '//*[@a="a1"]'));
if( $res eq $exp_res) { print "ok 75\n"; }
else { print "not ok 75\n"; warn "should return $exp_res, returned $res"; }
$res='';
$exp_res='p1';
$res .= $_->text foreach ($t->get_xpath( 'p[string()= "p1"]'));
if( $res eq $exp_res) { print "ok 76\n"; }
else { print "not ok 76\n"; warn "should return $exp_res, returned $res"; }
$doc='p1 p
p3
p2 ';
$res='';
$exp_res='p1p';
$t= new XML::Twig( TwigHandlers =>
{ '[@ns:a="a1"]' => sub { $res .= $_[1]->text; } });
$t->parse( $doc);
if( $res eq $exp_res) { print "ok 77\n"; }
else { print "not ok 77\n"; warn "should return $exp_res, returned $res"; }
$res='';
$res2='';
$exp_res2='p2';
$t= new XML::Twig( TwigHandlers =>
{ '[@ns:a="a1"]' => sub { $res .= $_[1]->text; },
'[@ns:a="a2"]' => sub { $res2 .= $_[1]->text; } });
$t->parse( $doc);
if( $res eq $exp_res) { print "ok 78\n"; }
else { print "not ok 78\n"; warn "should return $exp_res, returned $res"; }
if( $res2 eq $exp_res2) { print "ok 79\n"; }
else { print "not ok 79\n"; warn "should return $exp_res2, returned $res2"; }
$elt= XML::Twig::Elt->new( 'p', { att => 'val', '#EMPTY' => 0 });
$res= $elt->sprint;
$exp_res= '
';
if( $res eq $exp_res) { print "ok 80\n"; }
else { print "not ok 80\n"; warn "returns $res instead of $exp_res\n"; }
exit 0;
XML-Twig-3.50/t/test2_1.xml 0000644 0001750 0001750 00000002573 12346001775 015535 0 ustar mrodrigu mrodrigu
]>
S1 I1
S1 I2
S1 Title
S1 P1
S2 P2
Note P1
S1 para 3
S2 intro
S2 Title
S2 P1
S2 P2
S2 P3
Annex Title
Annex P1
Annex P2
XML-Twig-3.50/t/test_even_more_coverage.t 0000755 0001750 0001750 00000000617 12346001775 020610 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
# test designed to improve coverage of the module
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
#$|=1;
my $DEBUG=0;
use XML::Twig;
my $TMAX=1;
print "1..$TMAX\n";
{ my $t= XML::Twig->new( parse_start_tag => sub { return 'a'; })->parse( 'c ');
is( $t->sprint, 'c ', "dummy parse_start_tag");
}
exit 0;
XML-Twig-3.50/t/xmlxpath_29desc_with_predicate.t 0000755 0001750 0001750 00000000674 12346001774 022012 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
use Test;
plan( tests => 4);
use XML::Twig::XPath;
ok(1);
my $t= XML::Twig::XPath->new->parse( \*DATA);
ok( $t);
my @bbb = $t->findnodes( '/descendant::BBB[1]');
ok(@bbb, 1);
ok($bbb[0]->string_value, "OK");
exit 0;
__DATA__
OK
NOT OK
XML-Twig-3.50/t/test_additional.t 0000755 0001750 0001750 00000352127 12346001775 017074 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
# test designed to improve coverage of the module
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
my $DEBUG=0;
use XML::Twig;
my $perl= $];
my $open;
BEGIN
{ if( $] < 5.008)
{ $open= sub { return }; }
else
{ $open= eval( 'sub { open( $_[0], $_[1], $_[2]) }'); }
}
my $TMAX=663;
print "1..$TMAX\n";
{
my $t= XML::Twig->new->parse( q{
foo ]]> bar
});
# use CDATA
my $cdata= $t->first_elt( CDATA)->text;
is( $cdata, 'cdata 01', 'first_elt( CDATA)');# test 1
is( $t->first_elt( CDATA)->cdata_string, '', 'cdata_string');# test 2
is( $t->root->cdata_string, '', 'cdata_string for non cdata element');# test 3
my $cdata2= $t->root->first_child( 'cdata[2]')->next_elt( CDATA)->text;
is( $cdata2, 'cdata <02>', 'first_child( cdata[2])');# test 4
}
# test warning for invalid options
my $old_warning_handler= $SIG{__WARN__};
{
my $warning="";
$SIG{__WARN__} = sub { $warning.= join '', @_ };
XML::Twig->new( dummy_opt => 1);
$SIG{__WARN__}= $old_warning_handler;
chomp $warning;
matches( $warning, qr{^invalid option DummyOpt}, "expecting 'invalid option DummyOpt...', got '$warning'");# test 5
# test no warming if more_options is used
$warning="";
$SIG{__WARN__} = sub { $warning.= join '', @_ };
XML::Twig->new( more_options => 1, dummy_opt => 1);
$SIG{__WARN__}= $old_warning_handler;
nok( $warning, "expecting no warning, got '$warning'");# test 6
$warning="";
$SIG{__WARN__} = sub { $warning.= join '', @_ };
XML::Twig::add_options( 'dummy_opt');
XML::Twig->new( dummy_opt => 1);
$SIG{__WARN__}= $old_warning_handler;
nok( $warning, "expecting no warning (2), got '$warning'");# test 7
}
{
# test do_not_chain_handlers
my $nb_calls=0;
my $t= XML::Twig->new( twig_handlers => { chain => sub { $nb_calls++; 1;},
'doc/chain' => sub { $nb_calls++; 1;},
},
)->parse( 'chained ');
is( $nb_calls, 2, "chained calls");# test 8
$nb_calls=0;
$t= XML::Twig->new( twig_handlers => { chain => sub { $nb_calls++; 1 },
'doc/chain' => sub { $nb_calls++; 1 },
},
do_not_chain_handlers => 1,
)->parse( 'chained ');
is( $nb_calls, 1, "not chained calls");# test 9
$nb_calls=0;
$t= XML::Twig->new( twig_handlers => { chain => sub { $nb_calls++; 0; },
'doc/chain' => sub { $nb_calls++; 0; },
},
)->parse( 'chained ');
is( $nb_calls, 1, "chained handlers returning 0");# test 10
}
# test ignore_elt
{ my $t= XML::Twig->new( ignore_elts => { i1 => 1, i2 => 2})
->parse( '
');
my @t= $t->findnodes( '//t');
my $nb_t= scalar @t;
is( $nb_t, 4, 'findnodes //t');# test 11
}
# test elt_class
{
my $t= XML::Twig->new( elt_class => 'twig_test')->parse( ' ');
package twig_test;
use base 'XML::Twig::Elt';
sub test { return 25 }
package main;
is( $t->root->test, 25, 'elt_class');# test 12
}
# test char_handler
{
my $t= XML::Twig->new( char_handler => sub { my $s= shift; $s=~ s/\w/./g; return $s; })
->parse( 'foo baz ');
my $text= $t->root->text;
is( $text, '......', 'silly char_handler');# test 13
my $att= $t->root->last_child( 'elt')->att( 'att');
is( $att, 'bar', 'last_child');# test 14
$att= $t->root->last_child( 'elt')->att( 'att'); # to use the cache
is( $att, 'bar', 'last_child');# test 15
}
# test various methods
{ my $t= XML::Twig->new->parse( ' ');
my @new_children= $t->root->children_copy;
$t->set_id_seed( 'toto_');
$_->add_id foreach @new_children;
my $id= $new_children[0]->att( 'id');
is( $id, 'toto_1', 'copy att');# test 16
$new_children[1]->change_att_name( id => 'foo');
my $foo= $new_children[1]->att( 'foo');
is( $foo, 'toto_2', 'change_att_name');# test 17
ok( $t->root->all_children_are( 'elt'), "all_children_are( 'elt')");# test 18
nok( $t->root->all_children_are( 'none'), "all_children_are( 'none')");# test 19
my $count= $t->root->children_count( 'elt');
is( $count, 2, "children_count( 'elt')");# test 20
$count= $t->root->children_count( 'none');
is( $count, 0, "children_count( 'none')");# test 21
$count= $t->root->children_count;
is( $count, 2, "children_count");# test 22
ok( $t->root->first_child_matches( 'elt'), "first_child_matches");# test 23
$t->root->insert_new_elt( 'p');
nok( $t->root->all_children_are( 'elt'), "all_children_are( 'elt') (with p child)");# test 24
}
# test cdata append_cdata, append_extra_data, append_pcdata
{
my $t=XML::Twig->new->parse( 'text more text ');
my $cdata= $t->root->next_elt( CDATA)->cdata;
is( $cdata, 'some cdata', 'created CDATA element');# test 25
$t->root->next_elt( CDATA)->append_cdata( ' appended<>');
$t->root->next_elt( PCDATA)->append_pcdata( 'more ');
$t->root->first_child( 'elt')->append_extra_data( '');
is( $t->sprint, 'text more ]]> more text ', "append_extra_data");# test 26
}
# test att_names and att_to_field
{
my $t= XML::Twig->new->parse( ' ');
my $elt= $t->root->first_child_matches( 'elt');
ok( $elt, "first_child_matches");# test 27
my $att_names= join ':', sort $elt->att_names;
is( $att_names, 'att1:att2', "att_names");# test 28
$elt->att_to_field( 'att1');
$elt->att_to_field( att2 => "new");
my $elt_string= $elt->sprint;
is( $elt_string, 'bar foo ', "att_to_field")# test 29
}
# test child_matches child_text child_trimmed_text children_text
{
my $t= XML::Twig->new->parse( ' text text text ');
my $root= $t->root;
ok( $root->child_matches( 1, 'elt2'), "child_matches");# test 30
my $text= $root->child_text( 0);
is( $text, ' text ', "child_text");# test 31
$text= $root->child_trimmed_text( -1, 'elt2');
is( $text, 'text text', "child_trimmed_text", 25 );# test 32
$text= join( '-', $root->children_text( qr/elt/));
is( $text, ' text - text text', "children_text");# test 33
}
# test _ancestors _children _descendants
{ my $t= XML::Twig->new->parse( ' ');
is( tags( $t->root->_children), 'elt1:elt2', "_children");# test 34
is( tags( $t->root->_descendants), 'elt1:elt2:elt3', "_descendants");# test 35
is( $t->root->last_child_matches( 'elt3') ? "matches" : "no match",# test 36
"no match", "last_child_matches (no match)");
my $elt3= $t->root->last_child_matches( 'elt2')->first_child;
is( $elt3->gi, 'elt3', "last_child_matches (match)");# test 37
is( tags( $elt3->_ancestors), 'elt2:doc', "_ancestors");# test 38
is( tags( $elt3->_ancestors(1)), 'elt3:elt2:doc', "_ancestors(1)");# test 39
is( tags( $t->root->descendants( 'elt1')), 'elt1', 'descendants with gi');# test 40
is( tags( $t->root->descendants()), 'elt1:elt2:elt3', 'descendants without gi');# test 41
is( tags( $t->root->descendants( qr/^elt/)), 'elt1:elt2:elt3', 'descendants with qr');# test 42
is( tags( $t->root->descendants( qr/^elt/)), 'elt1:elt2:elt3', 'descendants with qr (using cache)');# test 43
}
# test comment methods
{
my $t= XML::Twig->new( comments => 'process')
->parse( 'text ');
my $comment= $t->first_elt( '#COMMENT');
is( $comment->comment, ' foo ', "comment");# test 44
is( $comment->comment_string, '', "comment");# test 45
}
# test element creation
{
my $t= XML::Twig->new->parse( ' ');
my $root= $t->root;
my $elt= $root->insert_new_elt( first_child => 'elt');
my $elt3= $elt->insert_new_elt( after => elt3 => "elt3 text");
my $elt2= $elt3->insert_new_elt( before => elt2 => { att => "foo" }, "elt2 text");
is( $t->sprint, 'elt2 text elt3 text ',# test 46
"insert_new_elt");
$root->cut_children;
is( $t->sprint, ' ', "cut_children");# test 47
$elt= $root->insert_new_elt( last_child => 'elt' => { '#ASIS' => 1 }, "bar
");
is( $elt->is_asis ? 'asis' : 'not asis', 'asis', "is_asis (initial, yes)");# test 48
is( $t->sprint, 'bar
', "insert_new_elt (ASIS)");# test 49
$elt->set_not_asis;
is( $elt->is_asis ? 'asis' : 'not asis', 'not asis', "is_asis (unset, no)");# test 50
is( $t->sprint, '<p>bar</p> ', "set_not_asis");# test 51
$elt->set_asis;
is( $elt->is_asis ? 'asis' : 'not asis', 'asis', "is_asis (set, yes)");# test 52
is( $t->sprint, 'bar
', "set_asis");# test 53
$root->cut_children;
$root->insert_new_elt( first_child => '#CDATA' => "toto");
is( $t->sprint, ' ', "create CDATA");# test 54
is($root->last_child_matches( '#CDATA') ? "match" : "no match", "match", "last_child_matches (yes)");# test 55
is($root->last_child_matches( "foo") ? "match" : "no match", "no match", "last_child_matches (no)");# test 56
my $cdata= $root->last_child_matches( '#CDATA');
ok( $cdata->is_cdata, "cdata is_cdata");# test 57
nok( $cdata->is_comment, "cdata is_comment");# test 58
nok( $cdata->is_pi, "cdata is_pi");# test 59
nok( $cdata->is_empty, "cdata is_empty");# test 60
nok( $cdata->is_ent, "cdata is_ent");# test 61
ok( $cdata->is_first_child, "cdata is_first_child");# test 62
ok( $cdata->is_last_child, "cdata is_last_child");# test 63
}
# test field last_child_text last_child_trimmed_text
{ my $t= XML::Twig->new->parse( 'val1 val2 ');
my $root= $t->root;
$root->set_field( field2 => "new val2 ");
is( $root->last_child_text( 'field2'), "new val2 ", "set_field");# test 64
is( $root->last_child_trimmed_text( 'field2'), "new val2", "set_field (trimmed text)");# test 65
is( $root->last_child_text( 'field1'), "val1", "last_child_text");# test 66
$root->set_field( field3 => "val3");
is( $t->sprint, 'val1 new val2 val3 ',# test 67
"set_field (new field)");
}
# test next/prev navigation functions
{ my $t= XML::Twig->new->parse(
q{elt 1
elt 2
elt 3 elt 4
elt 5
}
);
my $root= $t->root;
my $elt1= $t->getElementById( 'elt_1');
is( $elt1->sprint, 'elt 1 ', "getElementById");# test 68
my $sect= $elt1->getElementById( 'sect_1');
is( $sect->sprint, 'elt 3 elt 4 ', "getElementById (sect)");# test 69
ok( $elt1->next_elt_matches( '#PCDATA[text()="elt 1"]'), "next_elt_matches (elt1 => elt)");# test 70
ok( $elt1->prev_elt_matches( 'doc'), "prev_elt_matches (elt1 => doc)");# test 71
ok( $sect->next_elt_matches( 'elt[@id="elt_3"]'), "next_elt_matches (sect => elt_3)");# test 72
ok( $sect->prev_elt_matches( '#PCDATA[text()="elt 2"]'), "prev_elt_matches (sect => elt_2)");# test 73
is( $sect->next_elt_text( 'elt[@id="elt_5"]'), 'elt 5 ', "next_elt_text");# test 74
is( $sect->next_elt_trimmed_text( 'elt[@id="elt_5"]'), 'elt 5', "next_elt_trimmed_text");# test 75
nok( $sect->next_elt( $sect, 'elt[@id="elt_5"]'), "next_elt (outside the subtree)");# test 76
nok( $sect->next_elt_text( $sect, 'elt[@id="elt_5"]'), "next_elt_text (outside the subtree)");# test 77
is( $sect->first_child_trimmed_text, "elt 3", "first_child_trimmed_text");# test 78
is( $sect->first_child_trimmed_text( 'goofy'), "", "first_child_trimmed_text (no child)");# test 79
# test comparisons $elt1 < $sect < $elt3
my $elt3= $t->elt_id( 'elt_3');
ok( $elt1->le( $sect), "\$elt1 le \$sect");# test 80
ok( $elt1->lt( $sect), "\$elt1 lt \$sect");# test 81
nok( $elt1->ge( $sect), "\$elt1 ge \$sect");# test 82
nok( $elt1->gt( $sect), "\$elt1 gt \$sect");# test 83
nok( $elt3->le( $sect), "\$elt3 le \$sect");# test 84
nok( $elt3->lt( $sect), "\$elt3 lt \$sect");# test 85
ok( $elt3->ge( $sect), "\$elt3 ge \$sect");# test 86
ok( $elt3->gt( $sect), "\$elt3 gt \$sect");# test 87
}
# test keep_attribute_order
{ eval { require Tie::IxHash; };
if( $@) { skip( 7, "Tie::IxHash not available"); }
else
{ import Tie::IxHash;
my $t= XML::Twig->new( keep_atts_order => 1)
->parse( ' ');
is( $t->sprint, ' ', "keep_atts_order");# test 88
ok( $t->keep_atts_order, "keep_atts_order");# test 89
$t= XML::Twig->new->parse( ' ');
is( $t->sprint, ' ', "do not keep_atts_order");# test 90
nok( $t->keep_atts_order, "keep_atts_order not used");# test 91
$t->set_keep_atts_order(1);
my $elt1= $t->root->new( 'elt');
$elt1->set_att( a1 => 'v1');
$elt1->set_att( a2 => 'v2');
is( $elt1->sprint, ' ', 'keep_atts_order with new elt');# test 92
my $elt2= $t->root->new( 'elt');
$elt2->set_att( a2 => 'v2');
$elt2->set_att( a1 => 'v1');
is( $elt2->sprint, ' ', 'keep_atts_order with new elt (reverse order)');# test 93
XML::Twig::Elt::set_keep_atts_order(0);
my $elt3= $t->root->new( 'elt');
$elt3->set_att( a2 => 'v2');
$elt3->set_att( a1 => 'v1');
is( $elt3->sprint, ' ', 'no keep_atts_order with new elt (reverse order)');# test 94
}
}
# test wrap_children xml_string
{
my $t= XML::Twig->new->parse( ' ');
$t->set_id_seed( 'id_');;
$t->root->wrap_children( '+', wrap => { foo => "bar"});
is( $t->sprint, ' ', "wrap_children");# test 95
$t->root->strip_att( 'id');
is( $t->sprint, ' ', "wrap_children");# test 96
is( $t->root->xml_string, ' ', "xml_string");# test 97
}
# test set_output_encoding xml_text
{
my $t= XML::Twig->new->parse( 'elt 1 elt 2 ');
is( $t->root->xml_text, 'elt 1 elt 2', "xml_text");# test 98
is( $t->root->xml_string, 'elt 1 elt 2 ', "xml_text");# test 99
$t->set_output_filter( sub { return '.' x length $_[0] });
is( $t->root->xml_text, '...........', "xml_text (encoded)");# test 100
is( $t->root->xml_string, '.................................', "xml_text (encoded)");# test 101
}
# is_first_child is_last_child test contains_a_single contains_only
{
my $t= XML::Twig->new->parse( q{
e2_1
e2_2 e2_3
e2_4 e2_5 e3_1
});
my $elt1= $t->root->first_child('*');
my $elt2= $t->root->child( 1);
my $elt3= $t->root->first_child( sub { $_[0]->children_count( 'elt3') == 1 });
my $elt4= $t->root->last_child;
nok( $t->root->child( 6), 'child(6)');# test 102
nok( $t->root->child( -6), 'child(-6)');# test 103
nok( $t->root->child( 1, 'foo'), 'child(1, foo)');# test 104
nok( $t->root->child( -1, 'foo'), 'child(-1, foo)');# test 105
nok( $elt4->child( 1), 'child(1) on empty elt on empty elt');# test 106
nok( $elt4->child( 1, 'foo'), 'child(1, foo) on empty elt');# test 107
nok( $elt4->child( -1), 'child(-1) on empty elt');# test 108
nok( $elt4->child( -1, 'foo'), 'child(-1, foo) on empty elt');# test 109
ok( $elt1->is_first_child, "\$elt1->is_first_child");# test 110
nok( $elt2->is_first_child, "\$elt2->is_first_child is false");# test 111
nok( $elt3->is_first_child, "\$elt3->is_first_child is false");# test 112
nok( $elt1->is_last_child, "\$elt1->is_last_child");# test 113
nok( $elt2->is_last_child, "\$elt2->is_last_child");# test 114
ok( $elt4->is_last_child, "\$elt3->is_last_child is false");# test 115
ok( $elt1->contains_a_single( 'elt2'), "\$elt1->contains_a_single( 'elt2')");# test 116
nok( $elt1->contains_a_single( 'elt'), "\$elt1->contains_a_single( 'elt')");# test 117
nok( $elt2->contains_a_single( 'elt2'), "\$elt2->contains_a_single( 'elt2')");# test 118
nok( $elt3->contains_a_single( 'elt2'), "\$elt3->contains_a_single( 'elt2')");# test 119
nok( $elt4->contains_a_single( 'elt2'), "\$elt4->contains_a_single( 'elt2')");# test 120
ok( scalar $elt1->contains_only( 'elt2'), "\$elt1->contains_only( 'elt2')");# test 121
nok( $elt1->contains_only( 'elt'), "\$elt1->contains_only( 'elt') is false");# test 122
ok( scalar $elt2->contains_only( 'elt2'), "\$elt2->contains_only( 'elt2')");# test 123
nok( $elt3->contains_only( 'elt2'), "\$elt3->contains_only( 'elt2') is false");# test 124
ok( $elt4->contains_only( 'elt2'), "elt4->contains_only( 'elt2')");# test 125
is( $elt1->next_sibling_text, $elt2->text, "next_sibling_text");# test 126
is( $elt1->next_sibling_text, $elt2->text, "next_sibling_text using the cache");# test 127
is( $elt1->parent_text, $t->root->text, "parent_text");# test 128
is( $elt1->parent_text('doc'), $t->root->text, "parent_text");# test 129
is( $elt1->first_child->parent_text('doc'), $t->root->text, "parent_text");# test 130
ok( $elt2->parent_matches( 'doc'), "elt->parent_matches( 'doc')");# test 131
nok( $elt2->parent_matches( 'elt'), "elt->parent_matches( 'elt') is false");# test 132
nok( $t->root->parent, 'root parent');# test 133
nok( $t->root->parent_matches( 'doc'), 'root parent( doc)');# test 134
nok( $t->root->parent_matches( 'foo'), 'root parent( foo)');# test 135
is( $elt2->level, 1, "level");# test 136
is( $elt2->level( 'elt'), 0, "level( elt)");# test 137
is( $elt2->level( 'doc'), 1, "level( doc)");# test 138
is( $elt2->level( 'foo'), 0, "level( foo)");# test 139
nok( $elt2->first_child_text( 'foo'), "first_child_text on empty elt( 'foo')");# test 140
nok( $elt2->first_child_trimmed_text( 'foo'), "first_child_trimmed_text on empty elt( 'foo')");# test 141
nok( $elt4->next_sibling, 'next_sibling on last');# test 142
nok( $elt4->first_child, 'first_child on empty');# test 143
nok( $elt4->last_child, 'last_child on empty');# test 144
nok( $elt4->next_sibling_text, 'next_sibling_text on last');# test 145
nok( $elt4->first_child_text, 'first_child_text on empty');# test 146
nok( $elt4->last_child_text, 'last_child_text on empty');# test 147
nok( $elt4->next_sibling_trimmed_text, 'next_sibling_trimmed_text on last');# test 148
nok( $elt4->first_child_trimmed_text, 'first_child_trimmed_text on empty');# test 149
nok( $elt4->last_child_trimmed_text, 'last_child_trimmed_text on empty');# test 150
nok( $elt1->prev_sibling, 'prev_sibling on last');# test 151
nok( $elt1->prev_sibling_text, 'prev_sibling_text on last');# test 152
nok( $elt1->prev_sibling_trimmed_text, 'prev_sibling_trimmed_text on last');# test 153
}
# test next_n_elt del_id delete empty_tag_style
{
my $t= XML::Twig->new->parse( ' ');
my $elt= $t->root->next_n_elt( 1);
is( $elt->gi, 'elt', "next_n_elt");# test 154
is( $t->elt_id( 'id1')->gi, 'elt', "elt_id");# test 155
$elt->del_id;
is( $t->sprint, ' ', "del_id");# test 156
nok( $t->elt_id( 'id1'), "no elt_id( 'id1')");# test 157
$elt->set_id( 'id2');
is( $t->sprint, ' ', "set_id");# test 158
is( $t->elt_id( 'id2')->gi, "elt", "elt_id after set_id");# test 159
$elt->delete;
is( $t->sprint, ' ', "delete");# test 160
$t->root->insert_new_elt( first_child => '#COMMENT' => "a comment");
is( $t->sprint, ' ', "add comment");# test 161
$elt= $t->root->insert_new_elt( last_child => elt => { '#EMPTY' => 1 });
is( $t->sprint, ' ', "empty element");# test 162
ok( $elt->is_empty, "\$elt is empty");# test 163
$elt->set_not_empty;
is( $t->sprint, ' ', "non empty element");# test 164
nok( $elt->is_empty, "\$elt is not empty");# test 165
$elt->set_empty;
ok( $elt->is_empty, "\$elt is empty");# test 166
is( $t->sprint, ' ', "empty element again");# test 167
$t->set_empty_tag_style( 'html');
is( $t->sprint, ' ', "empty element (html style)");# test 168
XML::Twig::Elt::set_empty_tag_style( 'expand');
is( $t->sprint, ' ', "empty element (expand style)");# test 169
$t->set_empty_tag_style( 'normal');
is( $t->sprint, ' ', "empty element (normal style)");# test 170
$elt->set_content( "toto");
nok( $elt->is_empty, "\$elt is not empty");# test 171
is( $t->sprint, 'toto ', "element with content");# test 172
nok( $elt->prev_sibling_matches( '#PI'), "prev_sibling_matches nok");# test 173
my $comment= $elt->prev_sibling_matches( '#COMMENT');
ok( $comment, "prev_sibling_matches ok");# test 174
$comment= $elt->prev_sibling;
is( $comment->gi, '#COMMENT', 'prev_sibling');# test 175
$comment= $elt->prev_sibling;
is( $comment->gi, '#COMMENT', 'prev_sibling using the cached cond');# test 176
$comment= $elt->prev_sibling( '#COMMENT');
is( $comment->gi, '#COMMENT', 'prev_sibling');# test 177
$comment= $elt->prev_sibling( '#COMMENT');
is( $comment->gi, '#COMMENT', 'prev_sibling using the cached cond');# test 178
$comment->set_comment( "another comment");
is( $t->sprint, 'toto ', "element with content");# test 179
$t->root->field_to_att( 'elt');
is( $t->sprint, ' ', "field_to_att");# test 180
$t->root->del_att( 'elt');
$t->root->first_child( '#COMMENT')->delete;
is( $t->sprint, ' ', "back to a very simple doc");# test 181
$t->root->insert( elt => { att => "v2" });
$t->root->first_child->set_content( "val 3");
$t->root->insert_new_elt( first_child => elt => { att => "v1" }, "val 2");
$t->root->insert_new_elt( last_child => elt => { att => "v3" }, "val 1");
is( $t->sprint, 'val 2 val 3 val 1 ',# test 182
"insert 3 elements");
$t->root->sort_children_on_value;
is( $t->sprint, 'val 1 val 2 val 3 ',# test 183
"sort_children_on_value");
$t->root->sort_children_on_att( "att", order => "reverse" );
is( $t->sprint, 'val 1 val 3 val 2 ',# test 184
"sort_children_on_att (reverse)");
$t->root->set_text( "fini fini");
is( $t->sprint, 'fini fini ', 'set_text on root');# test 185
my $p= $t->root->insert( 'p');
my $new_p= $p->split_at( 4);
is( $t->sprint, 'fini
fini
', "split_at");# test 186
my $alt1_p= $p->copy;
my $alt2_p= $p->copy;
$p->split( qr/(i)/, 'b' );
is( $p->sprint, 'fi ni
', "split");# test 187
$alt1_p->first_child->split( qr/(i)/, 'b' );
is( $alt1_p->sprint, 'fi ni
', "split");# test 188
$new_p->split( qr/(i)/, b => { foo => "bar" } );
is( $new_p->sprint, ' fi ni
', "split (with att)");# test 189
}
# test start_tag_handlers
{
my @results;
my $handler;
my $t=XML::Twig->new( start_tag_handlers =>{ elt => \&sth1});
sub sth1
{ my( $t, $elt)= @_;
push @results, "handler 1: ". $elt->id;
$handler= $t->setStartTagHandler( elt => \&sth2);
}
sub sth2
{ my( $t, $elt)= @_;
push @results, "handler 2: ". $elt->id;
$t->setStartTagHandler( elt => $handler);
}
$t->parse( ' ');
is( shift @results, "handler 1: id1", "handler 1");# test 190
is( shift @results, "handler 2: id2", "handler 2");# test 191
is( shift @results, "handler 1: id3", "handler 1 again");# test 192
}
{
my $t= XML::Twig->new( pi =>'process')->parse( ' ');
my $pi= $t->root->first_child( '#PI');
$pi->set_target( 't2');
$pi->set_data( 'data2');
is( $pi->sprint, '', "pi");# test 193
my $elt= $pi->next_sibling;
$elt->set_extra_data( '');
is( $elt->sprint, " ", "elt with comment");# test 194
}
{
my $t= XML::Twig->new->parse( " elt 1 \n elt 2 ");
my $elt1= $t->root->first_child;
my $elt2= $t->root->last_child;
is( $elt2->prev_sibling_text, ' elt 1 ', "prev_sibling_text");# test 195
is( $elt2->prev_sibling_trimmed_text, 'elt 1', "prev_sibling_trimmed_text");# test 196
is( $elt1->next_sibling_trimmed_text, 'elt 2', "next_sibling_trimmed_text");# test 197
ok( $elt1->next_sibling_matches( 'elt'), "next_sibling_matches ok");# test 198
nok( $elt2->next_sibling_matches( 'elt'), "next_sibling_matches nok");# test 199
is( $elt2->prev_elt_text( 'elt'), " elt 1 ", "prev_elt_text");# test 200
is( $elt2->prev_elt_trimmed_text( 'elt'), "elt 1", "prev_elt_trimmed_text");# test 201
is( $elt2->parent_trimmed_text, "elt 1 elt 2", "parent_trimmed_text");# test 202
is( $elt1->sibling( 1)->trimmed_text, "elt 2", "sibling(1)");# test 203
is( $elt2->sibling( -1)->trimmed_text, "elt 1", "sibling(-1)");# test 204
is( $elt1->sibling_text( 1), " elt 2 ", "sibling(1)");# test 205
is( $elt2->sibling_text( -1), " elt 1 ", "sibling(-1)");# test 206
is( scalar $elt1->next_siblings, 1, "next_siblings");# test 207
is( scalar $elt1->next_siblings( 'elt2'), 0, "next_siblings (none)");# test 208
}
{
my $t= XML::Twig->new->parse( ' ');
my $elt1= $t->first_elt( 'elt1');
my $elt2= $t->first_elt( 'elt2');
$elt2->move( before => $elt1);
is( $t->sprint, ' ', "cut");# test 209
$elt2->cut;
is( $t->sprint, ' ', "cut");# test 210
$elt2->replace( $elt1);
is( $t->sprint, ' ', "replace");# test 211
$elt2->set_content( "toto");
$elt2->suffix( ":foo");
is( $elt2->xml_string, "toto:foo", "suffix");# test 212
$elt2->first_child( '#TEXT')->suffix( 'bar');
is( $elt2->xml_string, "toto:foobar", "suffix on pcdata elt");# test 213
$elt2->replace_with( $elt1);
is( $t->sprint, ' ', "replace_with");# test 214
$elt1->set_content( "tto");
my $o= XML::Twig::Elt->new( b => "oo");
$o->paste_within( $elt1, 1);
is( $t->sprint, 'too to ', "replace_with");# test 215
$o->new( t => {a => 1 }, 'ta')->paste_within( $t->first_elt( 'b')->first_child, 1);
is( $t->sprint, 'tota o to ', "replace_with");# test 216
}
# test methods inherited from XML::Parser::Expat
{
my $t= XML::Twig->new( twig_handlers => { elt => \&test_inherited })
->parse( 'toto ');
sub test_inherited
{ my( $t, $elt)= @_;
is( $t->depth, 2, "depth");# test 217
ok( $t->in_element( 'sect'), "in_element");# test 218
nok( $t->in_element( 'elt'), "in_element (false)");# test 219
ok( $t->within_element( 'sect'), "within_element");# test 220
ok( $t->within_element( 'doc'), "within_element");# test 221
nok( $t->within_element( 'elt'), "within_element (false)");# test 222
is( join( '/', $t->context), "doc/sect", "context");# test 223
is( $t->current_line, 1, "current_line");# test 224
is( $t->current_byte, 20, "current_byte");# test 225
is( $t->original_string, " ", "original_string");# test 226
is( $t->recognized_string, " ", "recognized_string");# test 227
is( $t->current_element, "sect", "current_element");# test 228
if( $XML::Parser::VERSION>2.27)
{ is( $t->element_index, 3, "element_index"); }# test 229
else
{ is( $t->element_index, 2, "element_index"); } # alt test 229
$t->base( "foo");
is( $t->base, "foo", "base");# test 230
ok( $t->position_in_context( 1), "position_in_context");# test 231
my $xml= 'toto ';
my $expected= '<elt>toto</elt>';
my $broken= '<elt>toto';
my $xml_escape= $t->xml_escape( $xml);
if( $xml_escape eq $broken)
{ warn "your version of expat/XML::Parser has a broken xml_escape method\n";
ok( 1, "xml_escape"); # test# test 232
}
else
{ is( $xml_escape, $expected, "xml_escape"); } # alt test 232
$xml= 'toto ';
$expected= '<elt>toto</elt>';
$broken= '<elt>toto';
$xml_escape= $t->xml_escape( $xml, 'o');
if( $xml_escape eq $expected)
{ ok( 1, "xml_escape"); }# test 233
elsif( $xml_escape eq $broken)
{ ok( 1, "xml_escape"); } # alt test 233
else
{ is( $xml_escape, $expected, "xml_escape"); } # alt test 233
}
}
{
my $t= XML::Twig->new( start_tag_handlers => { i => sub { $_[0]->ignore }, },
twig_handlers => { s => sub { $_[0]->finish }, } )
->parse( 'foo toto toto bar ');
is( $t->sprint, "foo toto ", "ignore + finish");# test 234
}
# test xml declaration and entity related methods
{
my $t= XML::Twig->new->parse( '
tata
">
]>
&ent1; &ent2; ');
is( $t->xml_version, "1.0", "xml_version");# test 235
is( $t->encoding, "ISO-8859-1", "encoding");# test 236
nok( $t->standalone, "standalone (no)");# test 237
is( $t->xmldecl, qq{\n}, "xmldecl");# test 238
$t->set_xml_version( "1.1");
is( $t->xml_version, "1.1", "set_xml_version");# test 239
$t->set_encoding( "UTF-8");
is( $t->encoding, "UTF-8", "set_encoding");# test 240
$t->set_standalone( 1);
ok( $t->standalone||'', "set_standalone");# test 241
is( $t->xmldecl, qq{\n}, "xmldecl");# test 242
is( join( ':', sort $t->entity_names), "ent1:ent2:ent3", "entity_names");# test 243
my $ent1= $t->entity( 'ent1');
is( $ent1->name, "ent1", "entity name");# test 244
is( $ent1->val, "toto", "entity val");# test 245
nok( $ent1->sysid, "entity sysid (none)");# test 246
nok( $ent1->pubid, "entity pubid (none)");# test 247
nok( $ent1->ndata, "entity ndata (none)");# test 248
my $ent3= $t->entity( 'ent3');
is( $ent3->name, "ent3", "entity name");# test 249
nok( $ent3->val, "entity val (none)");# test 250
is( $ent3->sysid, "ent3.png", "entity sysid");# test 251
nok( $ent3->pubid, "entity pubid (none)");# test 252
is( $ent3->ndata, "PNG", "entity ndata");# test 253
my $doctype= qq{\ntata">\n\n]>\n};
is( $t->doctype, $doctype, "doctype");# test 254
my $ent4= $t->entity_list->add_new_ent( ent4 => "ent 4")->ent( 'ent4');
is( $ent4->text, qq{}, "add_new_ent");# test 255
my $ent5= $t->entity_list->add_new_ent( ent5 => "", "ent5.png", "", "PNG" )->ent( 'ent5');
is( $ent5->text, qq{}, "add_new_ent (ndata)");# test 256
is( join( ':', sort $t->entity_names), "ent1:ent2:ent3:ent4:ent5", "entity_names");# test 257
is( $t->doctype, $doctype, "doctype");# test 258
my $prolog=qq{
tata">
]>
};
is( $t->prolog( UpdateDTD => 1), $prolog, "prolog, updated DTD");# test 259
$t->entity_list->delete( 'ent3');
is( join( ':', sort $t->entity_names), "ent1:ent2:ent4:ent5", "entity_names");# test 260
$t->entity_list->delete( ($t->entity_list->list)[0]);
is( join( ':', sort $t->entity_names), "ent2:ent4:ent5", "entity_names");# test 261
}
{
my $t= XML::Twig->new( comments => 'process', pi =>'process')
->parse( 'text ');
is( $t->root->first_child( '#COMMENT')->get_type, "#COMMENT", "get_type #COMMENT");# test 262
is( $t->root->first_child( '#PI')->get_type, "#PI", "get_type #PI");# test 263
is( $t->root->first_child( '#CDATA')->get_type, "#CDATA", "get_type #CDATA");# test 264
is( $t->root->first_child( '#PCDATA')->get_type, "#PCDATA", "get_type #PCDATA");# test 265
is( $t->root->get_type, "#ELT", "get_type #ELT");# test 266
my $cdata= $t->root->first_child( '#CDATA');
$cdata->set_cdata( "new cdata");
is( $cdata->sprint, "", "set_cdata");# test 267
my $copy= $t->root->copy;
is( $copy->sprint, $t->root->sprint, 'copy of an element with extra data');# test 268
is( $t->sprint( pretty_print => 'indented'),# test 269
qq{text \n},
'indented elt');
}
{
my $t= XML::Twig->new->parse( ' text &ent; more ');
my $ent= $t->first_elt( '#ENT');
is( $ent->get_type, "#ENT", "get_type");# test 270
is( $ent->ent, '&ent;', "ent");# test 271
is( $ent->ent_name, 'ent', "ent_name");# test 272
$ent->set_ent( '&new_ent;');
is( $ent->ent, '&new_ent;', "new_ent ent");# test 273
is( $ent->ent_name, 'new_ent', "new_ent ent_name");# test 274
}
{
my $t= XML::Twig->new->parse( 'text xx more text xx end ');
my $alt_root= $t->root->copy;
$t->root->mark( ' (xx) ', b => { att => "y" });
is( $t->sprint, 'textxx more textxx end ', 'mark');# test 275
$alt_root->first_child->mark( ' (xx) ', b => { att => "y" });
is( $alt_root->sprint, 'textxx more textxx end ', 'mark text');# test 276
}
{
my $t= XML::Twig->new->parse( ' ');
is( $t->sprint, ' ', "before save_global_state");# test 277
$t->save_global_state;
$t->set_quote( 'single');
is( $t->sprint, " ", "after set_global_state");# test 278
$t->restore_global_state;
is( $t->sprint, ' ', "after restore_global_state");# test 279
}
{
my $t= XML::Twig->new->parse( 'text bold text more text and text even more text ');
$t->subs_text( 'text', 'stuff');
is( $t->sprint, "stuff bold stuff more stuff and stuff even more stuff ", "subs_text");# test 280
$t->subs_text( qr{stuf+}, 'text');
is( $t->sprint, "text bold text more text and text even more text ", "subs_text");# test 281
my $elt= $t->root->first_child;
my $bold= $elt->first_child( 'b');
$bold->erase;
is( $t->sprint, "text bold text more text and text even more text ", "erase");# test 282
$elt->merge( $elt->next_sibling);
is( $elt->first_child_text, "text bold text more text and text even more text", "merge_text");# test 283
}
# more tests on subs_text
{
my $doc='link to http://www.xmltwig.org but do not link to http://bad.com, though link to toto and link to http://www.xml.com
now http://www.nolink.com and do not link to this and do not link to http://www.bad.com and do not link to http://www.bad2.com and link to http://link.com also
';
my $expected='see www.xmltwig.org but do not link to http://bad.com, though link to toto and see www.xml.com
now http://www.nolink.com and do not link to this and do not link to http://www.bad.com and do not link to http://www.bad2.com and see link.com also
';
my $t= XML::Twig->new->parse( $doc);
my $got= $t->subs_text( qr{(?{ href => $1 }, $2)');
is( $got->sprint, $expected, 'complex substitution with subs_text');# test 284
}
{
my $doc='text and more text
';
(my $expected= $doc)=~ s{ }{ }g;
my $t= XML::Twig->new->parse( $doc);
my $got= $t->subs_text( qr{ }, '&ent( " ")');
is( $got->sprint, $expected, 'creating entities with subs_text');# test 285
$t= XML::Twig->new->parse( $doc);
my $ent=" ";
$got= $t->subs_text( qr{ }, "&ent( '$ent')");
is( $got->sprint, $expected, 'creating entities from a variable with subs_text');# test 286
}
{
my $t= XML::Twig->new->parse(
'
03 val 1
2 val 2
4 val 3
01 val 4
05
');
$t->root->sort_children_on_field( 'key', type =>'numeric' );
my $expected=
'
01 val 4
2 val 2
03 val 1
4 val 3
05
';
$t->set_pretty_print( 'record_c');
$t->set_indent( ' ');
is( $t->sprint, $expected, "sort_children_on_field");# test 287
XML::Twig::Elt::set_indent( ' ');
}
{
my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none')->parse( ' ');
is( $t->sprint, " ", "empty_tags expand");# test 288
is( $t->sprint( empty_tags => 'normal'), " ", "empty_tags normal");# test 289
is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n \n", "empty_tags expand");# test 290
$t->set_pretty_print( 'none');
$t->set_empty_tag_style( 'normal');
}
{ if( $perl < 5.008)
{ skip( 3, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $out=''; my $out2='';
$open->( my $fh, ">", \$out);
$open->( my $fh2, ">", \$out2);
my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none')->parse( ' ');
$t->print( $fh);
is( $out, " ", "empty_tags expand");# test 291
$t->print( $fh2);
is( $t->sprint( empty_tags => 'normal'), " ", "empty_tags normal");# test 292
$out=''; $t->print( $fh);
is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n \n", "empty_tags expand");# test 293
$t->set_pretty_print( 'none');
$t->set_empty_tag_style( 'normal');
}
}
{ if( $perl < 5.008)
{ skip( 3, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $out=''; my $out2='';
$open->( my $fh, ">", \$out);
$open->( my $fh2, ">", \$out2);
my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none');
$t->parse( ' ')->flush( $fh);
is( $out, " ", "empty_tags expand");# test 294
$t->parse( ' ')->flush( $fh2);
is( $t->sprint( empty_tags => 'normal'), " ", "empty_tags normal");# test 295
$out=''; $t->parse( ' ')->flush( $fh);
is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n \n", "empty_tags expand");# test 296
$t->set_pretty_print( 'none');
$t->set_empty_tag_style( 'normal');
}
}
{
my $t= XML::Twig->new->parse(
'
03 val 1
2 val 2
4 val 3
01 val 4
');
$t->root->sort_children_on_field( 'key', type =>'numeric' );
my $expected=
'
01 val 4
2 val 2
03 val 1
4 val 3
';
$t->set_pretty_print( 'record_c');
$t->set_indent( ' ');
is( $t->sprint, $expected, "sort_children_on_field");# test 297
$t->set_indent( ' ');
}
{
my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none')->parse( ' ');
is( $t->sprint, " ", "empty_tags expand");# test 298
is( $t->sprint( empty_tags => 'normal'), " ", "empty_tags normal");# test 299
is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n \n", "empty_tags expand");# test 300
$t->set_pretty_print( 'none');
$t->set_empty_tag_style( 'normal');
}
{
my $t= XML::Twig->new->parse( ' ');
my $elt1= $t->root->first_child( 'elt');
my $elt2= $t->root->first_child( 'ns1:elt');
is( $elt1->namespace, "uri_def", "default namespace");# test 301
is( $elt2->namespace, "uri1", "namespace");# test 302
is( $elt1->namespace, "uri_def", "namespace default");# test 303
is( $elt1->namespace( 'ns1'), "uri1", "namespace not default");# test 304
is( join( ' - ', $elt1->current_ns_prefixes), '', "current_ns_prefixes");# test 305
is( join( ' - ', $elt2->current_ns_prefixes), ' - ns1', "current_ns_prefixes");# test 306
}
{
my $t=XML::Twig->new( ignore_elts => { i => 1 });
$t->parse( ' ');
is( $t->sprint, ' ', "setIgnoreEltsHandler");# test 307
}
{
my $t=XML::Twig->new;
$t->setIgnoreEltsHandler( i => 'discard');
$t->parse( ' ');
is( $t->sprint, ' ', "setIgnoreEltsHandler");# test 308
}
# test setEndTagHandler
{ my $called="";
my $t= XML::Twig->new( twig_roots => { title => 1 });
my $doc=q{title 1
title 2
};
$t->parse( $doc);
is( $called, "", "no end_tag_handler");# test 309
$called= '';
$t->setEndTagHandler( sect => sub { $called.= ":" if( $called); $called .= $_[1]});
$t->parse( $doc);
is( $called, "sect:sect", "end_tag_handler");# test 310
$called= '';
$t->setEndTagHandler( sect => sub { return });
$t->parse( $doc);
is( $called, "", "empty end_tag_handler");# test 311
}
# test replace_prefix
{ my $called='';
my $not_called='';
my $t= XML::Twig->new( namespaces => 1,
map_xmlns => { "uri1" => "foo", "uri2" => "whatever" },
twig_handlers => { "foo:bar" => sub { $called.= ":" if( $called);
$called .= $_->id
},
"toto:bar" => sub { $not_called.= ":" if( $not_called);
$not_called .= $_->id
},
},
);
$t->parse( q{
});
is( $called, "ok1:ok2", "map_xmlns");# test 312
is( $not_called, "", "map_xmlns (no hit)");# test 313
}
# test parser
{ my $t= XML::Twig->new( twig_handlers =>
{ doc => sub
{ is( ref( $_[0]->parser), 'XML::Parser::Expat', "parser"); } },# test 314
)
->parse( " ");
is( ref( $t->parser), '', "parser (empty, after the parse)");# test 315
$t->set_doctype( doc => "doc.dtd");
is( $t->sprint, qq{\n }, "set_doctype");# test 316
$t->set_doctype( doc => "doc.dtd", "-//public id/");
is( $t->sprint, qq{\n }, "set_doctype");# test 317
$t->set_doctype( doc => "doc.dtd", '', qq{[]});
is( $t->sprint, qq{\n]>\n }, "set_doctype");# test 318
#set_doctype ($name, $system, $public, $internal)
}
{ if( $perl < 5.008)
{ skip( 3, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $out='';
$open->( my $fh, ">", \$out);
my $doc= q{p1
p2
};
my $t= XML::Twig->new( twig_handlers => { flush => sub { $_->flush( $fh) } } );
$t->{twig_autoflush}=0;
$t->parse( $doc);
is( $out, q{p1
p2
}, "flush");# test 319
close $fh;
$out="";
$open->( $fh, ">", \$out);
$t= XML::Twig->new( twig_handlers => { flush => sub { $_[0]->flush_up_to( $_->prev_sibling, $fh) } } );
$t->{twig_autoflush}=0;
$t->parse( $doc);
is( $out, q{p1
p2
}, "flush_up_to");# test 320
$t= XML::Twig->new( twig_handlers => { purge => sub { $_[0]->purge_up_to( $_->prev_sibling->prev_sibling, $fh) } } )
->parse( q{p1
sp 1
});
is( $t->sprint, q{sp 1
}, "purge_up_to");# test 321
}
}
# test next_n_elt for a twig
{ my $t= XML::Twig->new->parse( q{e 2 e 3 });
is_undef( $t->next_n_elt( 1), "next_n_elt(1)");# test 322
is( $t->next_n_elt( 3)->gi, "e2", "next_n_elt(3)");# test 323
is( $t->next_n_elt( 1, "e3")->gi, "e3", "next_n_elt(1, e3)");# test 324
nok( $t->next_n_elt( 2, "e3"), "next_n_elt(2, e3)");# test 325
is( join(':', map { $_->gi } $t->_children), 'doc', "\$t->_children");# test 326
}
# test dtd_print
{ if( $perl < 5.008)
{ skip( 2, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{
{ my $out='';
$open->( my $fh, ">", \$out);
my $t= XML::Twig->new()->parse( q{]>toto });
$t->dtd_print( $fh);
is( $out, "\n\n]>\n", "dtd_print");# test 327
close $fh;
}
{ my $out="";
$open->( my $fh, ">", \$out);
my $t= XML::Twig->new( twig_handlers => { stop => sub { print $fh "[X]"; $_->set_text( '[Y]'); $_[0]->flush( $fh); $_[0]->finish_print( $fh); } });
$t->{twig_autoflush}=0;
$t->parse( q{before finish });
select STDOUT;
is( $out, q{[X]before[Y] finish }, "finish_print");# test 328
}
}
}
# test set_input_filter
{ my $t=XML::Twig->new( input_filter => \&rot13)
->parse( q{text });
is( $t->sprint, q{grkg }, "input filter");# test 329
$t=XML::Twig->new;
$t->parse( q{text });
is( $t->sprint, q{text }, "input filter (none)");# test 330
$t->set_input_filter( \&rot13);
$t->parse( q{grkg });
is( $t->sprint, q{text }, "set_input_filter");# test 331
$t->parse( ' ');
is( $t->sprint, ' ',# test 332
"set_input_filter on comments and cdata");
}
sub rot13 { $_[0]=~ tr/a-z/n-za-m/; $_[0]; }
# test global_state methods
{ my $doc= q{p 1
p 2
};
my $t=XML::Twig->new->parse( $doc);
is( $t->sprint, $doc, "initial state");# test 333
my $state= $t->global_state;
$t->set_pretty_print( 'indented');
$t->set_indent( 8);
nok( $t->sprint eq $doc, "changed state");# test 334
$t->set_global_state( $state);
is( $t->sprint, $doc, "re-set initial state");# test 335
$t->save_global_state;
$t->set_pretty_print( 'nice');
$t->set_quote( 'single');
nok( $t->sprint eq $doc, "changed state");# test 336
$t->restore_global_state( $state);
is( $t->sprint, $doc, "restored initial state");# test 337
}
# test encoding functions
{ if( $perl < 5.008)
{ skip( 21, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ require Encode; import Encode;
my $text= "\x{E9}t\x{E9}";
my $text_latin1 = encode( latin1 => $text);
my $text_utf8 = encode( utf8 => $text);
my $text_html="été";
my $text_safe= "été";
my $text_safe_hex= "été";
my $doc_latin1=qq{\n$text_latin1 };
my $doc_utf8=qq{\n$text_utf8 };
my $doc_html=qq{\n$text_html };
my $doc_safe=qq{\n$text_safe };
my $doc_safe_hex=qq{\n$text_safe_hex };
my $doc_escaped= xml_escape( $doc_html);
my $t= XML::Twig->new( output_encoding => "ISO-8859-1")->parse( $doc_utf8);
$t->save_global_state;
is( $t->output_encoding, 'ISO-8859-1', "output_encoding (ISO-8859-1)");# test 338
is( $t->sprint, $doc_latin1, "output_encoding ISO-8859-1");# test 339
$t->set_output_encoding( "UTF-8");
is( $t->output_encoding, 'UTF-8', "output_encoding (UTF-8)");# test 340
is( $t->sprint, $doc_utf8, "output_encoding UTF-8");# test 341
$t->set_output_text_filter( 'safe');
is( $t->sprint, $doc_safe, 'safe');# test 342
$t->set_output_text_filter( 'safe_hex');
is( $t->sprint, $doc_safe_hex, 'safe_hex');# test 343
if( $perl == 5.008)
{ skip( 2 => "cannot use latin1_output_text_filter with perl $perl"); }
else
{
$t->set_output_text_filter( $t->latin1 );
$t->set_output_encoding( "ISO-8859-1");
is( normalize_xml( $t->sprint( pretty_print => 'indented')), normalize_xml( $doc_latin1), 'latin1');# test 344
$t->set_output_filter( 'latin1' );
$t->set_output_encoding( "ISO-8859-1");
is( $t->sprint, $doc_latin1, 'latin1 (just the string)');# test 345
}
$t->set_output_text_filter( );
$t->set_output_encoding( "UTF-8");
$t->restore_global_state;
eval "require HTML::Entities";
if( $@)
{ skip( 4, "need HTML::Entities for those tests"); }
elsif( $perl == 5.008)
{ skip( 4, "HTML::Entities don't seem to work well with perl 5.8.0 (the e acute becomes é instead of é)"); }
else
{
import HTML::Entities;
$t->save_global_state;
$t->set_output_encoding( "UTF-8");
my $original_output_text_filter= $t->output_text_filter;
$t->set_output_text_filter( "html");
my $html_output_text_filter= $t->output_text_filter;
is( $t->sprint, $doc_html, "output_text_filter html");# test 346
$t->set_output_text_filter( $original_output_text_filter);
is( $t->sprint, $doc_utf8, "no output_text_filter ");# test 347
my $original_output_filter= $t->output_filter;
$t->set_output_filter( "html");
is( $t->sprint, $doc_escaped, "output_filter html");# test 348
$t->restore_global_state;
$t->set_output_encoding( "UTF-8");
is( $t->sprint, $doc_utf8, "no output_text_filter ");# test 349
}
$t->restore_global_state;
$t->set_output_encoding();
eval "require Text::Iconv";
if( $@)
{ skip( 3, "need Text::Iconv for those tests"); }
else
{ my $encoding= 'ISO-8859-1';
if( eval( '$t->iconv_convert( "$encoding");'))
{ $t->set_output_filter( $t->iconv_convert( $encoding) );
$t->set_encoding( $encoding);
is( $t->encoding, $encoding, "set_encoding");# test 350
is( $t->sprint, $doc_latin1, "output_filter ISO-8859-1 (using Text::Iconv)");# test 351
$t->restore_global_state;
$t->set_output_encoding( "UTF-8");
is( $t->sprint, $doc_utf8, "no output_filter ");# test 352
}
else
{ if( $@=~ m{^Unsupported encoding: $encoding})
{ skip( 3, "your version of iconv does not support $encoding"); }
else
{ skip( 3, "odd error creating filter with iconv: $@"); }
}
}
$t->restore_global_state;
$t->set_output_encoding();
eval( 'require Unicode::Map8 && require Unicode::String;');
if( $@)
{ skip( 3, "need Unicode::Map8 and Unicode::String for those tests" ); }
else
{ $t->set_output_filter( $t->unicode_convert( 'latin1') );
$t->set_encoding( "ISO-8859-1");
is( $t->encoding, "ISO-8859-1", "set_encoding");# test 353
is( $t->sprint, $doc_latin1, "output_filter latin-1 (using Unicode::*)");# test 354
$t->restore_global_state;
$t->set_output_encoding( "UTF-8");
is( $t->sprint, $doc_utf8, "no output_filter ");# test 355
$t->restore_global_state;
$t->set_output_encoding();
}
$t->set_output_filter( $t->regexp2latin1 );
$t->set_encoding( "ISO-8859-1");
is( $t->encoding, "ISO-8859-1", "set_encoding");# test 356
is( $t->sprint, $doc_latin1, "output_filter latin-1 (using regexp2latin1)");# test 357
$t->restore_global_state;
$t->set_output_encoding( "UTF-8");
is( $t->sprint, $doc_utf8, "no output_filter ");# test 358
$t->restore_global_state;
$t->set_output_encoding();
}
}
# test SAX1 export
{ eval "require XML::Handler::YAWriter";
if( $@)
{ skip(3, "require XML::Handler::YAWriter"); }
else
{ import XML::Handler::YAWriter;
my $xmldecl= qq{};
my $body= qq{text
};
my $doc= $xmldecl.$body;
my $t= XML::Twig->new->parse( $doc);
$t->root->set_att( '#priv' => 'private');
$t->root->insert_new_elt( last_child => '#private');
my $writer = XML::Handler::YAWriter->new( AsString => 1);
is( normalize_xml( $t->toSAX1( $writer)), $doc, 'toSAX1');# test 359
$writer->start_document;
$t->root->toSAX1( $writer);
is( normalize_xml( $writer->end_document), $doc, 'root toSAX1');# test 360
my $doc_flush=']>p 1
text more text &foo;
';
my $doc_flushed=qq{p 1
a
text more text bar
};
$writer = XML::Handler::YAWriter->new( AsString => 1, Pretty => { CatchEmptyElement => 1 });
$writer->start_document;
$SIG{__WARN__} = sub { };
$t= XML::Twig->new( twig_handlers =>
{ add => sub { $_[0]->flush_toSAX1( $writer);
$_->new( g => "a")->toSAX1( $writer);
},
flush => sub { $_[0]->flush_toSAX1( $writer); },
}
)
->parse( $doc_flush);
my $output= $t->flush_toSAX1( $writer) || '';
$SIG{__WARN__}= $old_warning_handler;
is( normalize_xml( $output), $doc_flushed, 'root toSAX1');# test 361
}
}
# test SAX2 export
{ eval "require XML::SAX::Writer;";
if( $@)
{ skip(5, "XML::SAX::Writer not available"); }
elsif( $XML::SAX::Writer::VERSION < 0.39)
{ skip( 5, "XML::SAX::Writer version 0.39 and above required to use SAX2 export"); }
else
{ eval "require XML::Filter::BufferText;";
if( $@)
{ skip(5, "XML::Filter::BufferText not available"); }
else
{ import XML::SAX::Writer;
import XML::Filter::BufferText;
my $output='';
my $writer = XML::SAX::Writer->new( Output => \$output);
my $xmldecl= qq{};
my $body= qq{text
foo:e text t
[ };
my $doc= $xmldecl.$body;
my $xfbtv= $XML::Filter::BufferText::VERSION;
if( $xfbtv < 1.01)
{ skip( 2, "XML::Filter::BufferText version $xfbtv has a bug in CDATA processing"); }
else
{
my $t= XML::Twig->new( comments =>'process', pi => 'process')->parse( $doc);
# add private data
$t->root->set_att( '#priv' => 'private');
$t->root->insert_new_elt( last_child => '#private');
$t->toSAX2( $writer);
is( normalize_xml( $output), $doc, 'toSAX2');# test 362
$output='';
$t->root->toSAX2( $writer);
is( normalize_xml( $output), $body, 'flush_toSAX2');# test 363
}
my $doc_flush="p 1
text more text
";
my $doc_flushed=qq{p 1
a
text more text
};
$output='';
my $t= XML::Twig->new( twig_handlers =>
{ add => sub { $_[0]->flush_toSAX2( $writer);
$_->new( g => "a")->toSAX2( $writer);
},
flush => sub { $_[0]->flush_toSAX2( $writer); },
}
)
->parse( $doc_flush);
$t->flush_toSAX2( $writer);
is( normalize_xml( $output), $doc_flushed, 'flush_toSAX2');# test 364
$doc= qq{]>toto = &toto; };
$t= XML::Twig->new()->parse( $doc);
$output='';
$writer = XML::SAX::Writer->new( Output => \$output);
$t->toSAX2( $writer);
$output=~ s{}{}s; # shows that in fact we have a problem with outputing the DTD
is( normalize_xml( $output), 'toto = foo ', 'toSAX2 with an entity');# test 365
$doc= qq{toto = &toto; };
$t= XML::Twig->new()->parse( $doc);
$output='';
$writer = XML::SAX::Writer->new( Output => \$output);
$t->toSAX2( $writer);
is( normalize_xml( $output), normalize_xml( $doc), 'toSAX2 with a non expanded entity');# test 366
}
}
}
# test flushed an twig_current status (not a very good test, but the methods are not used in practice)
{ my $t= XML::Twig->new->parse( ' ');
nok( $t->root->_flushed, "root is not flushed");# test 367
$t->root->_set_flushed;
ok( $t->root->_flushed, "root is flushed");# test 368
$t->root->_del_flushed;
nok( $t->root->_flushed, "root is not flushed");# test 369
nok( $t->root->{twig_current}, "root is not twig current");# test 370
$t->root->set_twig_current;
ok( $t->root->{twig_current}, "root is twig current");# test 371
$t->root->del_twig_current;
nok( $t->root->{twig_current}, "root is not twig current");# test 372
ok( $t->root->closed, "root is closed");# test 373
}
# test ignore
{ my $t= XML::Twig->new( start_tag_handlers => { ignore => sub { $_[0]->ignore },
ignore_parent => sub { $_->parent->ignore },
},
)
->parse( 'yes 1
no 1
yes 2
no 2
');
is( $t->sprint, 'yes 1
yes 2
', "ignore");# test 374
}
# test subs_text with replacement
{ my $doc= 'text rep text rep
text rep ';
(my $rep1= $doc)=~ s/rep/newr/g;
(my $rep2= $doc)=~ s{rep}{new }g;
(my $rep3= $rep2)=~ s{ }{ }g;
my $t= XML::Twig->new->parse( $doc);
$t->root->subs_text( qr/(r)ep/, 'new$1');
is( $t->sprint, $rep1, "subs_text");# test 375
$t->root->subs_text( qr/(new)r/, '&elt( b => $1)');
is( $t->sprint, $rep2, "subs_text (with elt)");# test 376
$t->root->subs_text( qr/ /, '&ent( " ")');
is( $t->sprint, $rep3, "subs_text (with ent)");# test 377
}
# test handlers that are not activated in 5.8
package test_handlers;
sub new { bless { } }
sub recognized_string { return 'recognized_string'; }
sub original_string { return 'original_string'; }
package main;
{ if( $perl < 5.008)
{ skip( 4, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{
my $out='';
$open->( my $fh, ">", \$out);
my $stdout= select $fh;
XML::Twig::_twig_print_original_default( test_handlers->new);
select $stdout;
close $fh;
is( $out, 'original_string', 'twig_print_original_default');# test 378
$out='';
$open->( $fh, ">", \$out);
select $fh;
XML::Twig::_twig_print( test_handlers->new);
select $stdout;
close $fh;
is( $out, 'recognized_string', 'twig_print');# test 379
$out='';
$open->( $fh, ">", \$out);
select $fh;
XML::Twig::_twig_print_end_original( test_handlers->new);
select $stdout;
close $fh;
is( $out, 'original_string', 'twig_print_end_original');# test 380
$out='';
$open->( $fh, ">", \$out);
select $fh;
XML::Twig::_twig_print( test_handlers->new);
select $stdout;
close $fh;
is( $out, 'recognized_string', 'twig_print');# test 381
}
XML::Twig::_twig_print_entity; # does nothing!
}
{
my %ents= ( foo => '"toto"', pile => 'SYSTEM "file.bar" NDATA bar');
my %ent_text = hash_ent_text( %ents);
my $ent_text = string_ent_text( %ents);
my $doc= " ";
my $t= XML::Twig->new->parse( $doc);
is( normalize_xml( $t->entity_list->text), $ent_text, 'entity_list');# test 382
my @entities= $t->entity_list->list;
is( scalar @entities, scalar keys %ents, 'entity_list');# test 383
if( $perl < 5.008)
{ skip( (scalar( keys %ents) + 1), "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{
foreach my $ent (@entities)
{ my $out='';
$open->( my $fh, ">", \$out);
my $stdout= select $fh;
$ent->print;
close $fh;
select $stdout;
is( normalize_xml( $out), $ent_text{$ent->name}, "print $ent->{name}"); # 2 tests 384 - 385
}
my $out='';
$open->( my $fh, ">", \$out);
my $stdout= select $fh;
$t->entity_list->print;
close $fh;
select $stdout;
is( normalize_xml( $out), $ent_text, 'print entity_list');# test 386
}
delete $ents{pile};
%ent_text = hash_ent_text( %ents);
$ent_text = string_ent_text( %ents);
$t->entity_list->delete( 'pile');
@entities= $t->entity_list->list;
is( scalar @entities, scalar keys %ents, '1 entity deleted');# test 387
is( $t->entity_list->text, $ent_text, 'entity_list (one entity deleted)');# test 388
}
{
if( $perl < 5.008)
{ skip( 3, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $out1=''; $open->( my $fh1, ">", \$out1);
my $out2=''; $open->( my $fh2, ">", \$out2);
my $out3=''; $open->( my $fh3, ">", \$out3);
my $stdout= select $fh3;
my $t= XML::Twig->new( twig_handlers => { e => sub { $_->print( $fh2);
print $fh1 "X";
$_[0]->finish_print( $fh1);
},
},
)
->parse( 'texte text
more text foo
');
print 'should be in $out3';
select $stdout;
is( $out1, 'Xmore text foo
', 'finish_print');# test 389
is( $out2, 'e text
', 'print to fh');# test 390
is( $out3, 'should be in $out3', 'restoring initial fh');# test 391
}
}
# test prefix mappings
package test_sax_prefix_mapping;
sub new { return bless { out => 'start ' }; }
sub start_element { my( $h, $element)= @_; $h->{out}.= "- start $element->{Name} "; }
sub end_element { my( $h, $element)= @_; $h->{out}.= "- end $element->{Name} "; }
sub start_prefix_mapping { my( $h, $map)= @_; $h->{out}.= "- map $map->{Prefix} to $map->{NamespaceURI} "; }
sub end_prefix_mapping { my( $h, $map)= @_; $h->{out}.= "- end map $map->{Prefix} "; }
sub end_document { my( $h, $document)= @_; return $h->{out}; }
package main;
{ my $h= test_sax_prefix_mapping->new;
my $t= XML::Twig->new->parse( q{text
text
});
my $out= $t->toSAX2( $h);
is( $out, 'start - map to uri1 - start doc - map p1 to uri2 - start p - start p1:e - end p1:e - end p - end map p1 - map p1 to uri3 - start p - start p1:e - end p1:e - end p - end map p1 - end doc - end map ', 'prefix mapping');# test 392
}
# test parsing with keep_encoding (to check no spurious warnings are produced)
{ my $warnings='';
$SIG{__WARN__}= sub { $warnings .= shift; };
my $doc= 'text
more text > é
';
my $t= XML::Twig->new( keep_encoding => 1)->parse( $doc);
$SIG{__WARN__}= $old_warning_handler;
is( $warnings, '', 'keep_encoding with elements with no attributes');# test 393
is( $t->sprint, $doc, 'twig output');# test 394
}
# test end_tag_handlers with ignore
{
my $out='';
my $t= XML::Twig->new( twig_roots => { p => 1 },
start_tag_handlers => { x => sub { $out .= "s" } },
twig_handlers => { n => sub { $out .="n";},
x => sub { $out .="e"; }
},
)
->parse( 'text text more text
');
is( $out, 'snese', 'end_tag_handlers without ignore');# test 395
$out='';
$t= XML::Twig->new( twig_roots => { p => 1 },
start_tag_handlers => { x => sub { $out .= "s"; $_->ignore } },
end_tag_handlers => { x => sub { $out .="e"; }, },
twig_handlers => { n => sub { $out .="n"; }, },
)
->parse( 'text text more text
');
is( $out, 'sese', 'end_tag_handlers with ignore');# test 396
eval ' XML::Twig->new( start_tag_handlers => { x => sub { $out .= "s"; $_->ignore } },
end_tag_handlers => { x => sub { $out .="e"; }, },
twig_handlers => { n => sub { $out .="n"; }, },
);
';
matches( $@, '^you should not use EndTagHandlers without', "error using end_tag_handlers");# test 397
$out='';
$t= XML::Twig->new( force_end_tag_handlers_usage => 1,
start_tag_handlers => { x => sub { $out .= "s"; $_->ignore } },
end_tag_handlers => { x => sub { $out .="e"; }, },
twig_handlers => { n => sub { $out .="n"; }, },
)
->parse( 'text text more text
');
is( $out, 'sesen', 'end_tag_handlers with ignore and force_end_tag_handlers_usage');# test 398
}
{ my @doc=( " ",
" ",
" ",
" ",
);
my( @r1, @r2, @r3, @r4);
my $t1= XML::Twig->new( ignore_elts => { lignore => 1 },
twig_handlers => { root => sub { push @r1, $_->tag; },
l1 => sub { push @r1, $_->tag; },
}
);
my $t2= XML::Twig->new( twig_handlers => { root => sub { push @r2, $_->tag; },
lignore => sub { $_->parent( 'l1')->ignore; },
},
);
my $t3= XML::Twig->new(
twig_handlers => { root => sub { push @r3, $_->tag; },
lignore => sub { $_->parent( 'l1')->ignore; },
},
end_tag_handlers => { l1 => sub { push @r3, $_[1]; }, },
force_end_tag_handlers_usage => 1
);
my $t4= XML::Twig->new( twig_roots => { l1 => sub { push @r4, 'l1 from roots handler'; },
lignore => sub { $_->parent( 'l1')->ignore; },
},
end_tag_handlers => { 'root/l1' => sub { push @r4, 'l1 from end_tag_handler'; }, },
);
my $i=0;
foreach my $doc (@doc)
{ @r1=(); @r2=(); @r3=(); @r4=();
$i++;
$t1->parse( $doc);
is( join( ':', @r1), "l1:root", "ignore_elt with twig_handlers $i (checking that stack is properly resized)");
$t2->parse( $doc);
is( join( ':', @r2), "root", "ignore_elt on ancestor with twig_handlers $i (checking that stack is properly resized)");
$t3->parse( $doc);
is( join( ':', @r3), "l1:root", "ignore_elt on ancestor with twig_handlers and end_tag_handlers $i (checking that stack is properly resized)");
$t4->parse( $doc);
is( join( ':', @r4), "l1 from end_tag_handler", "ignore_elt on ancestor with twig_roots and end_tag_handlers $i (checking that stack is properly resized)");
}
}
{
my $warning="";
$SIG{__WARN__} = sub { $warning .= join '', @_ };
my $t= XML::Twig->new( dummy_opt2 => 1);
$SIG{__WARN__}= $old_warning_handler;
matches( $warning, '^invalid option', "warning for extra option");# test 399
}
# test various handlers
{ my %got;
my $doc= '
foobar foo no
';
my @handler_exp= ( 'e', 'doc/e', '/doc/e', 'a[@a1]', 'a[@a2]', 'a[@a1="v11"]',
'a[@a1="v21"]', '*[@a1]', '*[@a1="v11"]', '*[@a1="v21"]', '*[@a1=~/^v21$/]',
't[string()="foobar"]', 't[string()=~ /^foo/]', 't[string()=~ /bar$/]',
'_default_',
);
my %handlers;
foreach my $exp (@handler_exp)
{ my $code= "\$got{\$_->id}||=[]; push \@{\$got{\$_->id}}, '$exp'; 1";
my $sub= eval "sub { $code }";
die "oops, error in test, code is '$code'" if( $@);
$handlers{$exp}= $sub;
}
my $t= XML::Twig->new( twig_handlers => \%handlers)->parse( $doc);
my %expected= ( e1 => [ '/doc/e', 'doc/e', 'e' ],
no1 => [ '_default_'],
a1 => [ '*[@a1]', '*[@a1="v11"]', 'a[@a1]', 'a[@a2]', 'a[@a1="v11"]' ],
a2 => [ '*[@a1]', '*[@a1="v21"]', 'a[@a1]', 'a[@a2]', 'a[@a1="v21"]', '*[@a1=~/^v21$/]' ],
b1 => [ '*[@a1]', '*[@a1="v11"]' ],
b2 => [ '*[@a1="v21"]', '*[@a1]', '*[@a1=~/^v21$/]'],
t1 => [ 't[string()="foobar"]', 't[string()=~ /^foo/]', 't[string()=~ /bar$/]' ],
t2 => [ 't[string()=~ /^foo/]' ],
t3 => [ '_default_'],
doc1 => [ '_default_'],
);
foreach my $elt (sort keys %expected)
{ my $expected= join( ' - ', sort @{$expected{$elt}});
my $got= $got{$elt} ? join( ' - ', sort @{$got{$elt}}) : '';
is( $got, $expected, "handlers on $elt"); # 10 tests 400 - 409
}
my %handlers2;
my %got2;
foreach my $exp (@handler_exp)
{ my $code= "\$got2{\$_->id}||=[]; push \@{\$got2{\$_->id}}, '$exp:2'; 1";
my $sub= eval "sub { $code }";
die "oops, error in test, code is '$code'" if( $@);
$t->setTwigHandler( $exp, $sub);
}
$t->parse( $doc);
foreach my $elt (sort keys %expected)
{ my $expected= join( ' - ', map { "$_:2" } sort @{$expected{$elt}});
my $got= $got2{$elt} ? join( ' - ', sort @{$got2{$elt}}) : '';
is( $got, $expected, "handlers on $elt (2)"); # 10 tests 410 - 419
}
}
{ my $t= XML::Twig->new->parse( ' ');
$t->change_gi( elt1 => 'elt2');
$t->change_gi( elt3 => 'elt4');
is( $t->sprint, ' ', 'change_gi');# test 420
}
# these do not pass (yet?)
{ my $doc= 'text
<ignored> more text
';
my $t= XML::Twig->new( start_tag_handlers => { i => sub { $_->ignore( 'string') }})
->parse( $doc);
is( $t->sprint, 'text
more text
', 'ignore');# test 421
$t->set_keep_encoding( 1);
$t->parse( $doc);
is( $t->sprint, 'text
more text
', 'ignore');# test 422
XML::Twig::Elt::set_keep_encoding( 0);
}
{ my $t= XML::Twig->new->parse( '
');
my $p= $t->first_elt( '*[@ns1:att=~/^f/]');
is( $p->namespace, 'uri', 'namespace on elt');# test 423
is( $p->namespace( 'ns1'), 'uri2', 'namespace with arg');# test 424
is( $p->namespace( 'xmlns'), 'http://www.w3.org/2000/xmlns/', 'namespace for xmlns');# test 425
is( $t->root->namespace(), '', 'default namespace');# test 426
is( $t->root->namespace( ''), '', 'namespace with arg default');# test 427
is( $t->root->namespace( 'xml'), 'http://www.w3.org/XML/1998/namespace', 'namespace for xml');# test 428
}
{ my $t= XML::Twig->new->parse( 'text ');
is( $t->root->first_child( 'e[@att="foo"]')->id, 'e2', 'cond on att value');# test 429
is( $t->root->first_child( '*[@att="foo"]')->id, 'f1', 'cond on att value (with wc)');# test 430
is( $t->root->first_child( '*[@att="foo" and @id="e2"]')->id, 'e2', 'and cond on att value');# test 431
is( $t->root->first_child( '*[@att="foo" or @id="e2"]')->id, 'f1', 'and cond on att value');# test 432
is( $t->root->first_child( 't[string()="text"]')->id, 't1', 'string cond');# test 433
is( $t->root->first_child( '*[string()="text"]')->id, 't1', 'string cond wc');# test 434
is( $t->root->first_child( 't[string()=~/^t/]')->id, 't1', 'regexp cond');# test 435
is( $t->root->first_child( '*[string()=~/^t/]')->id, 't1', 'regexp cond wc');# test 436
is( $t->root->first_child( qr/^t/)->id, 't1', 'regexp cond wc');# test 437
my $sprint= $t->root->first_child( 't')->sprint;
$t->root->first_child( 't')->change_att_name( 'foo');
is( $t->root->first_child( 't')->sprint, $sprint, 'change_att_name on non existent att');# test 438
my $ids= join ':', sort keys %{$t->{twig_id_list}};
my $elt= XML::Twig::Elt->new( 'e');
is( $elt->sprint, ' ', 'new elt');# test 439
$elt->del_id;
is( $elt->sprint, ' ', 'del_id, no id');# test 440
$elt->set_id( 'new_e');
is( $elt->sprint, ' ', 'set_id');# test 441
my( $new_ids)= join ':', sort keys %{$t->{twig_id_list}};
is( $new_ids, $ids, 'set_id on elt not in the tree');# test 442
$elt->del_id;
is( $elt->sprint, ' ', 'del_id, id removed');# test 443
nok( $t->first_elt( 'e')->next_elt( $t->first_elt( 'e')), 'next_elt on empty subtree');# test 444
nok( $t->first_elt( 'e')->next_elt($t->first_elt( 'e'), 'e'), 'next_elt on empty subtree');# test 445
is( $t->root->get_xpath( './e[1]', 0)->id, 'e1', 'get_xpath with ./');# test 446
is( $t->root->first_child->get_xpath( '/doc/e[1]', 0)->id, 'e1', 'get_xpath with /');# test 447
is( $t->root->first_child->get_xpath( '/doc/e[-1]', 0)->id, 'e3', 'get_xpath with /');# test 448
is( $t->root->first_child->get_xpath( './../e[2]', 0)->id, 'e2', 'get_xpath with ..');# test 449
is( $t->root->first_child->get_xpath( './../*[2]', 0)->id, 'f1', 'get_xpath with ../*[2]');# test 450
is( $t->root->first_child->get_xpath( './../*', 0)->id, 'e1', 'get_xpath with ../*');# test 451
}
{ my $t= XML::Twig->new->parse( ' ');
is( $t->root->cmp( $t->root), 0, 'cmp root with itself');# test 452
my $ne= $t->root->new( 'ne');
is( $ne->cmp( $ne), 0, 'cmp with itself');# test 453
is_undef( $t->root->cmp( $ne), 'cmp elt in different trees');# test 454
my $t_sprint= $t->sprint;
$t->root->field_to_att( 'foo');
is( $t->sprint, $t_sprint, 'field_to_att on wrong field');# test 455
my $ne_sprint= $ne->sprint;
$ne->field_to_att( 'foo');
is( $ne->sprint, $ne->sprint, 'field_to_att on wrong field (no child)');# test 456
$ne->prefix( 'p 1 pr', 'asis');
is( $ne->sprint, 'p 1 pr ', 'prefix asis');# test 457
$ne->prefix( 'p 2 ', 'asis');
is( $ne->sprint, 'p 2 p 1 pr ', 'prefix asis');# test 458
$ne->suffix( 's 1 su', 'asis');
is( $ne->sprint, 'p 2 p 1 prs 1 su ', 'prefix asis');# test 459
$ne->suffix( 's 2 ', 'asis');
is( $ne->sprint, 'p 2 p 1 prs 1 sus 2 ', 'prefix asis');# test 460
}
{ my $t= XML::Twig->new( twig_handlers => { w => sub { $_->wrap_in( 'ww'); } })
->parse( '
text
');
is( $t->sprint, '
text
', 'wrap current elt');# test 461
$t->root->wrap_in( 'd');
is( $t->sprint, '
text
', 'wrap root');# test 462
}
{ my $t= XML::Twig->new( twig_handlers => { w => sub { $_->parent->wrap_in( 'ww'); } })
->parse( 'text
');
is( $t->sprint, 'text
', 'wrap real current elt');# test 463
}
{ my $t= XML::Twig->new( twig_handlers => { w => sub { $_->parent->wrap_in( 'ww'); } })
->parse( 'text
');
is( $t->sprint, 'text
', 'wrap current elt');# test 464
}
my $doc=q{]> };
my $t= XML::Twig->new->parse( $doc);
(my $out= $t->sprint)=~ s{\n}{}g;
is( $out, $doc, 'doc with entities but no DTD');# test 465
# test is_first(last)_child
{ my $t= XML::Twig->new->parse( q{ });
my $root= $t->root;
$root->reset_cond_cache;
nok( $root->is_first_child(), 'root as first child');# test 466
nok( $root->is_last_child(), 'root as last child');# test 467
my $elt1= $root->first_child( 'elt1');
ok( $elt1->is_first_child(), 'first_child, no argument');# test 468
ok( $elt1->is_first_child( 'elt1'), 'first_child( elt1)');# test 469
nok( $elt1->is_first_child( 'elt2'), 'first_child( elt2)');# test 470
nok( $elt1->is_first_child( 'dummy'), 'first_child( dummy)');# test 471
nok( $elt1->is_last_child( ), 'last_child');# test 472
ok( $elt1->is_last_child( 'elt1'), 'last_child( elt1)');# test 473
nok( $elt1->is_last_child( 'elt2'), 'last_child( elt2)');# test 474
nok( $elt1->is_last_child( 'dummy'), 'last_child( dummy)');# test 475
}
# testing alternate start tag parser
{ my $t=XML::Twig->new( keep_encoding => 1, parse_start_tag => sub { return ( toto => att => 1)})
->parse( ' ');
is( $t->sprint, ' ', 'parse_start_tag');# test 476
}
{ my $t=XML::Twig->new( parse_start_tag => sub { return ( toto => att => 1)})
->parse( ' ');
is( $t->sprint, ' ', 'parse_start_tag');# test 477
}
# testing output_filter option
{ my $t= XML::Twig->new( output_filter => sub { return 'a' })->parse( ' ');
is( $t->sprint, 'a', 'output_filter option');# test 478
}
# testing output_text_filter option
{ my $t= XML::Twig->new( output_text_filter => sub { return 'a' })->parse( ' ');
is( $t->sprint, ' ', 'output_text_filter option');# test 479
}
# testing id option
{ my $t= XML::Twig->new( id => "foo")
->parse( 'bar ');
is( $t->elt_id( "f2")->sprint, 'bar ', 'id option');# test 480
}
# testing no_prolog option
{ my $t= XML::Twig->new( no_prolog => 1)
->parse( ' ');
is( $t->sprint, ' ', 'no_prolog option');# test 481
}
# testing no_prolog option
{ my $t= XML::Twig->new( no_prolog => 1, keep_encoding => 1)
->parse( ' ');
is( $t->sprint, ' ', 'no_prolog option');# test 482
}
# testing _all_ handler
{ my $nb_calls= 0;
my $t= XML::Twig->new( twig_handlers => { _all_ => sub { $nb_calls++ } })
->parse( 'text ');
is( $nb_calls, 3, '_all_ handler');# test 483
}
{ my $nb_calls= 0;
my $t= XML::Twig->new( start_tag_handlers => { _all_ => sub { $nb_calls++ } })
->parse( 'text ');
is( $nb_calls, 3, '_all_ handler (on starttag)');# test 484
}
# test changing handlers
# expressions in @exp must match the elements
{ my @exp= ( 'elt', 'doc/elt', '/doc/elt', 'elt[@att]', 'elt[@att="att1"]',
'*[@att]', '*[@att="att1"]', '*[@att=~/att/]',
'elt[@att=~/^att/]', '_default_',
'elt[string()="toto"]', 'elt[string()=~/to/]',
'elt[string(sub)="toto"]', 'elt[string(sub)=~/to/]',
);
my $doc= q{toto toto
toto toto
};
foreach my $exp (@exp)
{ my $res='';
my $t= XML::Twig->new( twig_handlers => { $exp => sub { $res .= "O"; },
change => sub { $res .= "C";
$_[0]->setTwigHandler( $exp => sub { $res .= "N"; });
nok( $_->closed, 'closed (on open element)');# 14 tests 485 - 498
},
doc => sub { }, # so _default_ doesnt find it
sub => sub { },
},
)
->parse( $doc);
is( $res, 'OOCNN', "changing handlers on $exp");# 14 tests 499 - 512
}
}
{ my $res='';
my $doc= q{toto toto
toto toto
toto toto
};
my %handlers= map { build_handler_on_att( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_handler_on_att( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( 'elt[@att="1"]', undef);
$_[0]->setTwigHandler( build_handler_on_att( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on atts");# test 513
sub build_handler_on_att
{ my( $prefix, $nb)= @_;
return( qq{elt[\@att="$nb"]} => sub { $res.= $prefix . $nb });
}
}
{ my $res='';
my $doc= q{toto toto
toto toto
toto toto
};
my %handlers= map { build_att_regexp_handler( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_att_regexp_handler( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( 'elt[@att=~ /1/]', undef);
$_[0]->setTwigHandler( build_att_regexp_handler( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on regexps on atts");# test 514
sub build_att_regexp_handler
{ my( $prefix, $nb)= @_;
return( qq{elt[\@att=~ /$nb/]} => sub { $res.= $prefix . $nb });
}
}
{ my $res='';
my $doc= q{toto toto
toto toto
toto toto
};
my %handlers= map { build_handler_on_star_att( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_handler_on_star_att( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( '*[@att="1"]', undef);
$_[0]->setTwigHandler( build_handler_on_star_att( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on star atts");# test 515
sub build_handler_on_star_att
{ my( $prefix, $nb)= @_;
return( qq{*[\@att="$nb"]} => sub { $res.= $prefix . $nb });
}
}
{ my $res='';
my $doc= q{toto toto
toto toto
toto toto
};
my %handlers= map { build_star_att_regexp_handler( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_star_att_regexp_handler( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( '*[@att=~ /1/]', undef);
$_[0]->setTwigHandler( build_star_att_regexp_handler( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on regexps on star atts");# test 516
sub build_star_att_regexp_handler
{ my( $prefix, $nb)= @_;
return( qq{*[\@att=~ /$nb/]} => sub { $res.= $prefix . $nb });
}
}
{ my $res='';
my $doc= q{1 2 3
1 1 3
1 2 1
};
my %handlers= map { build_string_handler( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_string_handler( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( 'elt[string()= "1"]', undef);
$_[0]->setTwigHandler( build_string_handler( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on elt[string()]");# test 517
sub build_string_handler
{ my( $prefix, $nb)= @_;
return( qq{elt[string()= "$nb"]} => sub { $res.= $prefix . $nb });
}
}
{ my $res='';
my $doc= q{1 2 3
1 1 3
1 2 1
};
my %handlers= map { build_regexp_handler( 'O', $_) } (1..3);
my $t= XML::Twig->new( twig_handlers => { %handlers,
change => sub { foreach( 1..3)
{ $_[0]->setTwigHandler( build_regexp_handler( 'N', $_)) }
},
change2 => sub { $_[0]->setTwigHandler( 'elt[string()=~ /1/]', undef);
$_[0]->setTwigHandler( build_regexp_handler( 'D', 2));
}
},
)
->parse( $doc);
is( $res, 'O1O2O3N1N1N3D2', "changing handlers on elt[string()]");# test 518
sub build_regexp_handler
{ my( $prefix, $nb)= @_;
return( qq{elt[string()=~ /$nb/]} => sub { $res.= $prefix . $nb });
}
}
# test PI and comment drops
{ my $doc= q{text more text };
(my $doc_without_pi = $doc)=~ s{<\?pi.*?\?>}{}g;
(my $doc_without_comment = $doc)=~ s{}{}g;
(my $doc_without_all = $doc)=~ s{<(\?pi|!--).*?(\?|--)>}{}g;
my $t= XML::Twig->new( pi => 'drop', comments => 'process')->parse( $doc);
is( normalize_xml( $t->sprint), $doc_without_pi, 'drop pis');# test 519
$t= XML::Twig->new( pi => 'process', comments => 'drop')->parse( $doc);
is( normalize_xml( $t->sprint), $doc_without_comment, 'drop comments');# test 520
$t= XML::Twig->new( pi => 'drop' , comments => 'drop')->parse( $doc);
is( normalize_xml( $t->sprint), $doc_without_all, 'drop comments and pis');# test 521
my $doc6=q{ text more text };
$t= XML::Twig->new( pi => 'keep')->parse( $doc6);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc6), 'keep pi');# test 522
my $doc5=q{ text more text };
$t= XML::Twig->new( pi => 'process')->parse( $doc5);
is( normalize_xml( $t->sprint), $doc5, 'process pi');# test 523
my $doc4=q{ text more text };
$t= XML::Twig->new->parse( $doc4);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc4), 'comment before PI (2 PIs, no comments)');# test 524
my $doc3=q{text more text };
$t= XML::Twig->new->parse( $doc3);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc3), 'comment before PI (2 PIs, no comments)');# test 525
my $doc1=q{ttext more text };
$t= XML::Twig->new->parse( $doc1);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc1), 'comment before PI (2 PIs, pcdata before pi)');# test 526
my $doc2=q{ text more text };
$t= XML::Twig->new->parse( $doc2);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc2), 'comment before PI (2 PIs)');# test 527
$t= XML::Twig->new->parse( $doc);
is( _hash( normalize_xml( $t->sprint)), _hash( $doc), 'comment before PI (3 PIs)');# test 528
}
# returns a string that has all the chars in the input, ordered, to allow
# comparison of texts without taking the order into consideration
sub _hash
{ return sort split //, $_[0]; }
{ my $doc=q{ };
my $res='';
my $t= XML::Twig->new( twig_roots => { root => 1 },
start_tag_handlers =>
{ 'elt1' => sub { $res.= 'E1'; },
'elt2[@att="a"]' => sub { $res .= 'E2'; },
'elt7[@att=~/b/]' => sub { $res .= 'E3'; },
'/doc/elt3' => sub { $res .= 'E4'; },
'elt3/elt4' => sub { $res .= 'E5'; },
'*[@att="c"]' => sub { $res .= 'E6'; },
'*[@att=~/d/]' => sub { $res .= 'E7'; },
_default_ => sub { $res .= 'E0'; }
},
)->parse( $doc);
is( $res => 'E0E1E2E3E4E5E6E7E0', 'all types of handlers on start_tags');# test 529
}
{ my $doc= q{ };
my $t= XML::Twig->new( keep_spaces => 1)->parse( $doc);
is( $t->sprint, $doc, 'spaces before cdata');# test 530
}
{ my $doc= q{ };
my $t= XML::Twig->new( keep_spaces => 1)->parse( $doc);
is( $t->sprint, $doc, '2 cdata sections');# test 531
}
{ my $doc= q{ };
my $t= XML::Twig->new( keep_spaces => 1, comments => 'process')->parse( $doc);
is( $t->sprint, $doc, 'spaces and extra data before cdata');# test 532
}
{ # fun with suffix and asis
my $t=XML::Twig->new->parse( 'to ');
$t->root->suffix( 'to');
is( $t->sprint, 'toto ', 'regular suffix');# test 533
$t=XML::Twig->new->parse( 'to ');
$t->root->suffix( 'to');
is( $t->sprint, 'to to ', 'regular suffix needs new elt');# test 534
$t=XML::Twig->new->parse( 'to ');
$t->root->suffix( ' ', 'asis');
is( $t->sprint, 'to ', 'asis suffix needs new elt');# test 535
$t=XML::Twig->new->parse( 'to ');
$t->root->suffix( ' ', 'asis');
is( $t->sprint, 'to ', 'asis suffix');# test 536
$t=XML::Twig->new->parse( '<to/> ');
$t->root->set_asis( 1);
$t->root->suffix( ' ', 'asis');
is( $t->sprint, ' ', 'asis suffix (on asis elt)');# test 537
$t=XML::Twig->new->parse( '<to/> ');
$t->root->set_asis( 1);
$t->root->suffix( ' ');
is( $t->sprint, ' <to/> ', 'regular suffix (on asis elt)');# test 538
}
{ # fun with prefix and asis
my $t=XML::Twig->new->parse( 'to ');
$t->root->prefix( 'to');
is( $t->sprint, 'toto ', 'regular prefix');# test 539
$t=XML::Twig->new->parse( 'to ');
$t->root->prefix( ' ', 'asis');
is( $t->sprint, 'to ', 'regular prefix needs new elt');# test 540
$t=XML::Twig->new->parse( 'to ');
$t->root->prefix( 'to');
is( $t->sprint, 'toto ', 'asis prefix needs new elt');# test 541
$t=XML::Twig->new->parse( 'to ');
$t->root->prefix( ' ', 'asis');
is( $t->sprint, ' to ', 'asis prefix');# test 542
$t=XML::Twig->new->parse( '<to/> ');
$t->root->set_asis( 1);
$t->root->prefix( ' ', 'asis');
is( $t->sprint, ' ', 'asis prefix (on asis elt)');# test 543
$t=XML::Twig->new->parse( '<to/> ');
$t->root->set_asis( 1);
$t->root->prefix( ' ');
is( $t->sprint, '<to/> ', 'regular suffix (on asis elt)');# test 544
}
{ # wrap_in on the current
my $t= XML::Twig->new( twig_handlers => { wrapped => sub { $_->wrap_in( wrapper => { foo => 'bar'} )} })
->parse( 'tototata ');
is( $t->sprint, 'tototata ', 'wrap_in');# test 545
}
{ my $t= XML::Twig->new->parse( q{ });
ok ( $t->first_elt( 'elt1')->has_no_atts, 'has_no_atts true');# test 546
nok( $t->first_elt( 'elt2')->has_no_atts, 'has_no_atts false');# test 547
nok( $t->first_elt( 'elt3')->has_no_atts, 'has_no_atts false');# test 548
nok ( $t->first_elt( 'elt1')->has_atts, 'has_atts false');# test 549
ok( $t->first_elt( 'elt2')->has_atts, 'has_atts true');# test 550
ok( $t->first_elt( 'elt3')->has_atts, 'has_atts true');# test 551
is( $t->first_elt( 'elt1')->att_nb, 0, 'att_nb, 0');# test 552
is( $t->first_elt( 'elt2')->att_nb, 1, 'att_nb, 1');# test 553
is( $t->first_elt( 'elt3')->att_nb, 2, 'att_nb, 2');# test 554
}
{ my $t= XML::Twig->new->parse( 'titi
');
$t->root->split( qr/(i)/);
is( $t->sprint, 't
i
ti
', "split with no tag");# test 555
}
{ my $t= XML::Twig->new->parse( 'titi toto
');
$t->root->split( 'b');
is( $t->sprint, 'titi toto
', "split with no regexp");# test 556
}
{ my $t= XML::Twig->new->parse( 'titi toto
');
$t->root->split( qr/foo/, 'ta');
is( $t->sprint, 'titi toto
', 'split, no match');# test 557
}
{ my $doc= ' toto &ent;
';
my $t= XML::Twig->new->parse( $doc);
my $alt_root= $t->root->copy;
is( $alt_root->sprint, $t->root->sprint, 'copy with entity');# test 558
}
{ my $doc= 'toto ';
my $t= XML::Twig->new->parse( $doc);
my $pcdata= $t->first_elt( '#TEXT');
my $start_tag= $pcdata->start_tag;
nok( $start_tag, 'start_tag for a text element');# test 559
$t->root->set_att( '#priv_att' => 1);
is( $t->sprint, $doc, 'private attributes');# test 560
my $priv_elt= $t->root->insert( '#priv_elt');
is( $t->sprint, $doc, 'private element');# test 561
$priv_elt->set_gi( 'foo');
is( $t->sprint, 'toto ', 'private element');# test 562
$priv_elt->set_gi( '#priv');
is( $t->sprint, $doc, 'private element');# test 563
$priv_elt->set_att( att => "val");
is( $t->sprint, $doc, 'private element');# test 564
$priv_elt->set_gi( 'foo');
is( $t->sprint, 'toto ', 'private element');# test 565
}
{ my $doc= qq{val1 val2 };
my $out= qq{\n\n \n \n val1 \n val2 \n \n \n};
my $t=XML::Twig->new( pretty_print => 'record')->parse( $doc);
is( $t->sprint, $out, 'record with empty record');# test 566
$t->set_pretty_print( 'none');
}
{ my $e= XML::Twig::Elt->new( 'toto');
nok( scalar $e->_is_private, 'private elt (not)');# test 567
$e->set_tag( '#toto');
ok( scalar $e->_is_private, 'private elt (yes)');# test 568
ok( scalar XML::Twig::Elt::_is_private_name( '#toto'), '_is_private_name (yes)');# test 569
nok( scalar XML::Twig::Elt::_is_private_name( 'toto'), '_is_private_name (no)');# test 570
}
{ my $t= XML::Twig->new->parse( ' ');
my $text_elt= $t->first_elt( '#TEXT');
is( $text_elt->xml_string, '', 'xml_string for cdata');# test 571
$text_elt->set_text( '<>');
is( normalize_xml( $t->sprint), ']]> ', 'set_text on CDATA');# test 572
$text_elt->set_text( '<>', force_pcdata => 1);
is( normalize_xml( $t->sprint), '<> ', 'set_text on CDATA (with force_pcdata)');# test 573
$t->root->set_content( { att => "val" }, 'toto ', 'tata');
is( $t->root->sprint, 'toto tata ', 'set_content with attributes');# test 574
$text_elt= $t->first_elt( '#TEXT');
$text_elt->set_content( 'titi');
is( $t->root->sprint, 'titi ', 'set_content on text elt');# test 575
}
{ my $t=XML::Twig->new->parse( 'text 1 text 2 text 3 ');
my $elt1= $t->root->first_child( 'elt[1]');
my $elt2= $t->root->first_child( 'elt[2]');
my $elt3= $t->root->first_child( 'elt[3]');
my $new1= XML::Twig::Elt->new( new => "new 1");
my $new2= XML::Twig::Elt->new( new => "new 2");
my $new3= XML::Twig::Elt->new( new => "new 3");
$new1->replace( $elt1);
$new2->replace( $elt2);
$new3->replace( $elt3);
is( $t->sprint, 'new 1 new 2 new 3 ', 'replace');# test 576
$new1->replace_with( $elt2, $elt1, $elt3);
is( $t->sprint, 'text 2 text 1 text 3 new 2 new 3 ', 'replace');# test 577
}
{
if( $perl < 5.008)
{ skip( 1, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $doc= 'tatat more ';
my $out=''; $open->( my $fh, ">", \$out);
my $t= XML::Twig->new( comments => 'process', pi => 'process')->parse( $doc);
$t->flush( $fh);
is( $out, $doc, 'flush with cdata');# test 578
}
}
{ my $doc=<
text this
text to
keep spaces
in like
this
END
my $t= XML::Twig->new( pretty_print => 'indented', keep_spaces_in => [ qw(pre) ])->parse( $doc);
(my $indented= $doc)=~ s{}{\n };
is( $t->sprint, $indented, 'indented with keep_spaces_in');# test 579
$t->set_pretty_print( 'indented');
}
{ my $doc='text ';
my $nsgmls= qq{text \n};
my $t= XML::Twig->new( pretty_print => 'nsgmls')->parse( $doc);
is( $t->sprint, $nsgmls, 'nsgmls style');# test 580
$t->set_pretty_print( 'indented');
}
{ my $t= XML::Twig->new->parse( 'text ');
$t->root->erase;
is( $t->root->sprint, "text \n", 'erase root');# test 581
}
{ my $t= XML::Twig->new->parse( ' ');
my $elt2= $t->first_elt( 'elt2');
ok( $elt2->sibling( 0, 'elt2'), 'sibling 0 (ok)');# test 582
nok( $elt2->sibling( 0, 'elt1'), 'sibling 0 (nok)');# test 583
nok( $elt2->sibling( 1, 'elt1'), 'sibling 1 (nok)');# test 584
nok( $elt2->sibling( -1, 'elt3'), 'sibling -1 (nok)');# test 585
ok( $elt2->in( 'doc'), 'in with condition');# test 586
ok( $elt2->in( $t->root), 'in with elt');# test 587
nok( $elt2->in( 'elt1'), 'in with condition (false)');# test 588
nok( $elt2->in( $t->root->last_child), 'in with elt (false)');# test 589
is( $elt2->prev_sibling( 'elt1[@att="val"]')->gi, 'elt1', '@att="val" condition');# test 590
nok( $elt2->prev_sibling( 'elt1[@att="val2"]'), '@att="val" condition (not found)');# test 591
is( $elt2->prev_sibling( 'elt1[@att=~ /val/]')->gi, 'elt1', '@att=~ /val/ condition');# test 592
nok( $elt2->prev_sibling( 'elt1[@att=~/val2/]'), '@att=~/val2/ condition (not found)');# test 593
}
{
if( $perl < 5.008)
{ skip( 2, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $out='';
$open->( my $fh, ">", \$out);
my $doc='text text ';
$t= XML::Twig->new( twig_roots=> { elt2 => 1 },
start_tag_handlers => { elt => sub { print $fh ' '; } },
end_tag_handlers => { elt3 => sub { print $fh ' '; } },
twig_print_outside_roots => $fh,
keep_encoding => 1
)
->parse( $doc);
is( $out, 'text text ',# test 594
'twig_print_outside_roots, start/end_tag_handlers, keep_encoding');
close $fh;
$out='';
$open->( $fh, ">", \$out);
$t= XML::Twig->new( twig_roots=> { elt2 => 1 },
start_tag_handlers => { elt => sub { print $fh ' '; } },
end_tag_handlers => { elt3 => sub { print $fh ' '; } },
twig_print_outside_roots => $fh,
)
->parse( $doc);
is( $out, 'text text ',# test 595
'twig_print_outside_roots and start_tag_handlers');
}
}
{ my $t= XML::Twig->new->parse( 'text 1
text 2
text 3
');
my @a1= $t->get_xpath( '/doc/elt[@att="a1"]');
is( ids( @a1), 'elt-1:elt-2', 'xpath /doc/elt[@att="a1"]');# test 596
@a1= $t->get_xpath( '/doc/*[@att="a1"]');
is( ids( @a1), 'elt-1:elt-2', 'xpath /doc/*[@att="a1"]');# test 597
@a1= $t->get_xpath( '/doc//*[@att="a1"]');
is( ids( @a1), 'elt-1:elt-2', 'xpath /doc//*[@att="a1"]');# test 598
@a1= $t->get_xpath( '//*[@att="a1"]');
is( ids( @a1), 'elt-1:elt-2', 'xpath //*[@att="a1"]');# test 599
@a1= $t->get_xpath( '//elt[@att="a1"]');
is( ids( @a1), 'elt-1:elt-2', 'xpath //elt[@att="a1"]');# test 600
my @a2= $t->get_xpath( '//elt2[@id="elt2-4" and @att2="a2"]');
is( ids( @a2), 'elt2-4', 'xpath //elt2[@id="elt2-4" and @att2="a2"]');# test 601
@a2= $t->get_xpath( '//elt2[@id="toto" or @att2="a2"]');
is( ids( @a2), 'elt2-2:elt2-4:elt2-6', 'xpath //elt2[@id="toto" or @att2="a2"]');# test 602
my $a2= $t->get_xpath( '//elt2[@id="toto" or @att2="a2"]', 1);
is( $a2->att( 'id'), 'elt2-4', 'xpath //elt2[@id="toto" or @att2="a2"], offset 1');# test 603
@a2= $t->get_xpath( \@a1, './elt2[@id="toto" or @att2="a2"]');
is( ids( @a2), 'elt2-2:elt2-4', 'xpath //elt2[@id="toto" or @att2="a2"] on @a1');# test 604
$a2= $t->findvalue( \@a1, './elt2[@id="toto" or @att2="a2"]');
is( $a2, 'text 1text 2', 'findvalue //elt2[@id="toto" or @att2="a2"] on @a1');# test 605
}
{ my $doc= qq{\n]>\ntoto &ent; \n};
my $t= XML::Twig->new( keep_encoding => 1)->parse( $doc);
is( $t->sprint, $doc, 'keep_encoding with entity');# test 606
}
# testing DTD parsing
{ my $doc= qq{\n\n]>\n };
my $t= XML::Twig->new->parse( $doc);
is( $t->sprint, $doc, 'simple DTD');# test 607
}
{ my $doc= qq{\n\n\n]>\n };
my $t= XML::Twig->new->parse( $doc);
is( $t->sprint, $doc, 'DTD 1 element and simple attlist');# test 608
}
{ my $doc=<
]>
text
DTD
my $t= XML::Twig->new( ErrorContext => 1)->parse( $doc);
is( $t->sprint, $doc, 'complex DTD');# test 609
is( join( ':', $t->model), 'doc:elt:elt2', 'model with no elt (all element in the dtd)');# test 610
}
# testing do_not_output_DTD option
{ my $t= XML::Twig->new( no_prolog => 1)
->parse( ']> ');
is( $t->sprint, ' ', 'no_prolog');# test 611
}
# testing do_not_output_DTD option
{ my $t= XML::Twig->new( do_not_output_DTD => 1)
->parse( ']> ');
is( $t->sprint, ' ', 'do_not_output_DTD option');# test 612
$t->purge;
}
# handlers on PIs
{ my $t= XML::Twig->new( pretty_print => 'none', twig_handlers => { '?t1' => sub { return ""; } })
->parse( 'toto ');
is( $t->sprint, 'toto ', 'handler on pi t1, with comment');# test 613
}
# handlers on PIs
{ my $t= XML::Twig->new( pretty_print => 'none', twig_handlers => { '?' => sub { return ""; } })
->parse( 'toto ');
is( $t->sprint, 'toto ', 'handler on all pi, with comment');# test 614
}
# creating an output encoding
{
if( $perl < 5.008)
{ skip( 1, "need perl 5.8 or above to perform these tests (you have $perl)"); }
else
{ my $t= XML::Twig->new->parse( ' ');
$t->set_output_encoding( 'ISO-8859-1');
is( $t->sprint, qq{ }, 'creating an output encoding');# test 615
}
}
# some calls that return false
{ my $root= XML::Twig->new->parse( ' ')->root;
nok( $root->last_child_matches( 'toto'), 'last_child_matches (not)');# test 616
nok( $root->first_child_matches( 'toto'), 'first_child_matches(not)');# test 617
nok( $root->child_text( 1, 'toto'), 'child_text(not)');# test 618
nok( $root->child_trimmed_text( 1, 'toto'), 'child_trimmed_text(not)');# test 619
nok( $root->child_matches( 1, 'toto'), 'child_matches(not)');# test 620
nok( $root->prev_sibling_matches( 'toto'), 'prev_sibling_matches(not)');# test 621
nok( $root->prev_elt_text( 'toto'), 'prev_elt_text(not)');# test 622
nok( $root->sibling_text( 1, 'toto'), 'prev_elt_text(not)');# test 623
nok( $root->prev_elt_trimmed_text( 'toto'), 'prev_elt_trimmed_text(not)');# test 624
nok( $root->prev_elt_matches( 'toto'), 'prev_elt_matches(not)');# test 625
nok( $root->next_elt_trimmed_text( 'toto'), 'next_elt_trimmed_text(not)');# test 626
nok( $root->next_elt_matches( 'toto'), 'next_elt_matches(not)');# test 627
nok( $root->parent_text( 'toto'), 'parent_text(not)');# test 628
nok( $root->parent_trimmed_text( 'toto'), 'parent_trimmed_text(not)');# test 629
nok( $root->pcdata_xml_string, 'pcdata_xml_string of a non pcdata elt');# test 630
nok( $root->att_xml_string( 'foo'), 'att_xml_string of a non existing att');# test 631
}
{ my $doc=<
text 1
text 2
text 1
text 2
END
my $expected_doc=q{
text 1
text 2
text 1 text 2 };
my $expected_s1= q{
text 1
text 2
};
my $expected_s2= q{text 1 text 2 };
my $t=XML::Twig->new(pretty_print => 'none')->parse( $doc);
is( $t->sprint, $expected_doc, 'doc with xml:space="preserve"');# test 632
is( $t->get_xpath( '//*[@id="s1"]', 0)->sprint, $expected_s1, 'sub element of an xml:space="preserve" element');# test 633
is( $t->get_xpath( '//*[@id="s2"]', 0)->sprint, $expected_s2, 'regular sub element');# test 634
}
{ my $e= XML::Twig::Elt->parse( ' ');
is( $e->xml_text, '', 'xml_text of an empty elt');# test 635
$e= XML::Twig::Elt->parse( 'toto ')->first_child;
is( $e->xml_text, 'toto', 'xml_text of a pcdata');# test 636
$e->set_content();
is( $e->xml_text, 'toto', 'empty set_content');# test 637
$e= XML::Twig::Elt->parse( ' ')->first_child;
is( $e->xml_text, '', 'xml_text of a cdata');# test 638
}
{ my $doc= q{toto }
. q{tata };
my $expected_keep= $doc;
$expected_keep=~ s{toto}{foo};
$expected_keep=~ s{tata}{bar};
my $t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
keep_original_prefix => 1,
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
is( $t->sprint, $expected_keep, "map_xmlns and keep_original_prefix");# test 639
$t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
(my $expected_remap= $expected_keep)=~ s{ns(?=\d)}{ns_}g;
is( $t->sprint, $expected_remap, "map_xmlns");# test 640
}
{ my $doc= q{toto }
. q{tata };
my $expected_keep= $doc;
$expected_keep=~ s{toto}{foo};
$expected_keep=~ s{tata}{bar};
my $t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
keep_original_prefix => 1,
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
is( $t->sprint, $expected_keep, "map_xmlns and keep_original_prefix");# test 641
$t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
(my $expected_remap= $expected_keep)=~ s{ns(?=\d)}{ns_}g;
is( $t->sprint, $expected_remap, "map_xmlns");# test 642
}
{ my $doc= q{toto }
. q{tata };
my $expected_keep= $doc;
$expected_keep=~ s{toto}{foo};
$expected_keep=~ s{tata}{bar};
my $t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
keep_original_prefix => 1,
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
is( $t->sprint, $expected_keep, "map_xmlns and keep_original_prefix with default ns");# test 643
$t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
(my $expected_remap= $expected_keep)=~ s{ns(?=\d)}{ns_}g;
$expected_remap=~ s{(?sprint, $expected_remap, "map_xmlns with default ns");# test 644
}
{ my $doc= q{toto }
. q{tata kaboom };
my $expected_keep= $doc;
$expected_keep=~ s{toto}{foo};
$expected_keep=~ s{tata}{bar};
my $t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
keep_original_prefix => 1,
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
is( $t->sprint, $expected_keep, "map_xmlns and keep_original_prefix with default ns");# test 645
$t= XML::Twig->new( map_xmlns => { uri1 => "ns_1", uri2 => "ns_2" },
twig_handlers => { 'ns_1:elt' => sub { $_->set_text( 'foo'); },
'ns_2:elt' => sub { $_->set_text( 'bar'); },
}
)
->parse( $doc);
(my $expected_remap= $expected_keep)=~ s{ns(?=\d)}{ns_}g;
$expected_remap=~ s{(?sprint, $expected_remap, "map_xmlns with default ns");# test 646
}
{ my $t= XML::Twig->new->parse( ' ');
my $elt= $t->root->insert( elt => { att => undef});
$elt->insert( '#PCDATA');
is( $t->sprint => ' ', "undef text and att");# test 647
}
exit 0;
XML-Twig-3.50/t/test_memory.t 0000755 0001750 0001750 00000010603 12346001774 016261 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use strict;
use Carp;
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
$|=1;
my $DEBUG=0;
use XML::Twig;
# only display warnings, test is too unreliable (especially under Devel::Cover) to trust
my $mem_size= mem_size();
unless( $mem_size)
{ print "1..1\nok 1\n";
warn "skipping: memory size not available\n";;
exit;
}
if( !XML::Twig::_weakrefs())
{ print "1..1\nok 1\n";
warn "skipping: weaken not available\n";;
exit;
}
my $long_test= $ARGV[0] && $ARGV[0] eq '-L';
my $conf= $long_test ? { iter => 10, p => 1000 }
: { iter => 5, p => 500 }
;
$conf->{normal}= $conf->{p} * $conf->{iter};
$conf->{normal_html}= $conf->{normal} * 2;
my $TMAX=6;
print "1..$TMAX\n";
my $warn=0;
my $paras= join '', map { qq{lorem ipsus whatever (clever latin stuff) no $_
}} 1..$conf->{p};
my $test_nb=1;
foreach my $wr (0..1)
{
# first pass if with weakrefs, second without
my $wrm='';
if( $wr)
{ XML::Twig::_set_weakrefs( 0);
$wrm= " (no weak references)";
}
{ my $xml= qq{$paras };
XML::Twig->new->parse( $xml);
my $before= mem_size();
for (1..$conf->{iter})
{ my $t= XML::Twig->new->parse( $xml);
if( $wr)
{ really_clear( $t) }
}
my $after= mem_size();
if( $after - $before > $conf->{normal})
{ warn "test $test_nb: possible memory leak parsing xml ($after > $before)$wrm"; $warn++; }
elsif( $long_test)
{ warn "$before => $after\n"; }
ok(1, "testing memory leaks for xml parsing$wrm");
$test_nb++;
}
{ if( XML::Twig::_use( 'HTML::TreeBuilder', 3.13))
{ my $html= qq{with HTB $paras};
XML::Twig->new->parse_html( $html);
my $before= mem_size();
for (1..$conf->{iter}) { XML::Twig->new->parse_html( $html); }
my $after= mem_size();
if( $after - $before > $conf->{normal_html})
{ warn "test $test_nb: possible memory leak parsing html ($after > $before)$wrm"; $warn++; }
elsif( $long_test)
{ warn "$before => $after\n"; }
ok(1, "testing memory leaks for html parsing$wrm");
}
else
{ skip( 1, "need HTML::TreeBuilder 3.13+"); }
$test_nb++;
}
{ if( XML::Twig::_use( 'HTML::Tidy'))
{ my $html= qq{with tidy $paras};
XML::Twig->new( use_tidy => 1)->parse_html( $html);
my $before= mem_size();
for (1..$conf->{iter}) { XML::Twig->new( use_tidy => 1)->parse_html( $html); }
my $after= mem_size();
if( $after - $before > $conf->{normal_html})
{ warn "test $test_nb: possible memory leak parsing html ($after > $before)$wrm"; $warn++; }
elsif( $long_test)
{ warn "$before => $after\n"; }
ok(1, "testing memory leaks for html parsing using HTML::Tidy$wrm");
}
else
{ skip( 1, "need HTML::Tidy"); }
$test_nb++;
}
}
if( $warn)
{ warn "\nnote that memory leaks can happen even if the module itself doesn't leak, if running",
"\ntests under Devel::Cover for exemple. So do not panic if you get a warning here.\n";
}
sub mem_size
{ open( STATUS, "/proc/$$/status") or return;
my( $size)= map { m{^VmSize:\s+(\d+\s+\w+)} } ;
$size=~ s{ kB}{};
#warn "data size found: $size\n";
return $size;
}
sub really_clear
{ my( $t)= shift;
my $elt= $t->root->DESTROY;
delete $t->{twig_dtd};
delete $t->{twig_doctype};
delete $t->{twig_xmldecl};
delete $t->{twig_root};
delete $t->{twig_parser};
return;
local $SIG{__WARN__} = sub {};
while( $elt)
{ my $nelt= nelt( $elt);
$elt->del_id( $t);
foreach ( qw(gi att empty former)) { undef $elt->{$_}; delete $elt->{$_}; }
$elt->delete;
$elt= $nelt;
}
$t->dispose;
}
sub nelt
{ my( $elt)= @_;
if( $elt->_first_child) { return deepest_child( $elt); }
if( $elt->_next_sibling) { return deepest_child( $elt->_next_sibling); }
return $elt->parent;
}
sub deepest_child
{ my( $elt)= @_;
while( $elt->_first_child) { $elt= $elt->_first_child; }
return $elt;
}
XML-Twig-3.50/t/xmlxpath_19axisd_or_s.t 0000755 0001750 0001750 00000001023 12346001774 020137 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools;
use Test;
plan( tests => 4);
use XML::Twig::XPath;
ok(1);
my $t= XML::Twig::XPath->new->parse( \*DATA);
ok( $t);
my @nodes;
@nodes = $t->findnodes( '/AAA/XXX/descendant-or-self::*');
ok(@nodes, 8);
@nodes = $t->findnodes( '//CCC/descendant-or-self::*');
ok(@nodes, 4);
exit 0;
__DATA__
XML-Twig-3.50/t/test_new_features_3_22.t 0000755 0001750 0001750 00000014210 12346001775 020164 0 ustar mrodrigu mrodrigu #!/usr/bin/perl -w
use strict;
use Carp;
use FindBin qw($Bin);
use File::Spec;
use lib File::Spec->catdir(File::Spec->curdir,"t");
use tools;
use XML::Twig;
my $DEBUG=0;
print "1..20\n";
{ my $doc= q{
]>
&foo; };
XML::Twig->new( keep_encoding => 1)->parse( $doc);
}
{ # testing parse_html
if( XML::Twig::_use( 'HTML::TreeBuilder', 3.13) && XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent'))
{ my $html= q{T t t2t3};
my $expected= HTML::TreeBuilder->new->parse( $html)->as_XML;
$expected=~ s{>(meta|br)}{ /}g;
is_like( XML::Twig->new->parse_html( $html)->sprint, $expected, 'parse_html string using HTML::TreeBuilder');
my $html_file= File::Spec->catfile( "t", "test_new_features_3_22.html");
spit( $html_file => $html);
if( -f $html_file)
{ is_like( XML::Twig->new->parsefile_html( $html_file)->sprint, $expected, 'parsefile_html using HTML::TreeBuilder');
open( HTML, "<$html_file") or die "cannot open HTML file '$html_file': $!";
is_like( XML::Twig->new->parse_html( \*HTML)->sprint, $expected, 'parse_html fh using HTML::TreeBuilder');
}
else
{ skip( 2, "could not write HTML file in t directory, check permissions"); }
}
else
{ skip( 3 => 'need HTML::TreeBuilder 3.13+ and LWP to test parse_html'); }
}
{ # testing _use
ok( XML::Twig::_use( 'XML::Parser'), '_use XML::Parser');
ok( XML::Twig::_use( 'XML::Parser'), '_use XML::Parser (2cd time)'); # second time tests the caching
nok( XML::Twig::_use( 'I::HOPE::THIS::MODULE::NEVER::MAKES::IT::TO::CPAN'), '_use non-existent-module');
nok( XML::Twig::_use( 'I::HOPE::THIS::MODULE::NEVER::MAKES::IT::TO::CPAN'), '_use non-existent-module (2cd time)');
}
{ # testing auto-new features
my $doc= ' ';
is( XML::Twig->nparse( empty_tags => 'normal', $doc)->sprint, $doc, 'nparse string');
is( XML::Twig->nparse( empty_tags => 'expand', $doc)->sprint, ' ', 'nparse string and option');
my $doc_file= 'doc.xml';
spit( $doc_file => $doc);
# doc is still expanded because empty_tags was set above
is( XML::Twig->nparse( $doc_file)->sprint, ' ', 'nparse file');
is( XML::Twig->nparse( twig_handlers => { doc => sub { $_->set_tag( 'foo'); } }, $doc_file)->sprint, ' ', 'nparse file and option');
unlink $doc_file;
if( XML::Twig::_use( 'HTML::TreeBuilder', 3.13) && XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent'))
{
$doc=q{
foo toto
};
is( XML::Twig->nparse( $doc)->sprint, $doc, 'nparse well formed html string');
$doc_file="doc.html";
spit( $doc_file => $doc);
is( XML::Twig->nparse( $doc_file)->sprint, $doc, 'nparse well formed html file');
#is( XML::Twig->nparse( "file://$doc_file")->sprint, $doc, 'nparse well formed url');
unlink $doc_file;
XML::Twig::_disallow_use( 'HTML::TreeBuilder');
eval{ XML::Twig->new->parse_html( ' '); };
matches( $@, "^cannot parse HTML: missing HTML::TreeBuilder", "parse_html without HTML::TreeBuilder");
XML::Twig::_allow_use( 'HTML::TreeBuilder');
}
else
{ skip( 3, "need HTML::TreeBuilder 3.13+"); }
if( XML::Twig::_use( 'HTML::TreeBuilder', 3.13) && XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent'))
{ $doc=q{foo toto tata
};
(my $expected= $doc)=~ s{ }{ };
$doc_file="doc.html";
spit( $doc_file => $doc);
is( XML::Twig->nparse( $doc_file)->sprint, $expected, 'nparse html file');
#is( XML::Twig->nparse( "file://$doc_file")->sprint, $doc, 'nparse html url');
unlink $doc_file;
}
else
{ skip ( 1, "need HTML::TreeBuilder 3.13+"); }
}
{
my $file= File::Spec->catfile( $Bin, "test_new_features_3_22.html");
if( -f $file)
{ XML::Twig::_disallow_use( 'LWP::Simple');
eval { XML::Twig->nparse( "file://$file"); };
matches( $@, "^missing LWP::Simple", "nparse html url without LWP::Simple");
XML::Twig::_allow_use( 'LWP::Simple');
if( XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent') && XML::Twig::_use( 'HTML::TreeBuilder', 3.13))
{ my $url= "file://$file";
$url=~ s{\\}{/}g; # we need a URL, not a file name
my $content= XML::Twig->nparse( $url)->sprint;
(my $expected= slurp( $file))=~ s{(<(meta|br)[^>]*>)}{$1$2>}g;
$expected=~s{t3}{
t3
};
$expected=~ s{>(meta|br)}{ /}g;
is( $content, $expected, "nparse url");
}
else
{ skip( 1 => "cannot test html url parsing without LWP::Simple and HTML::TreeBuilder 3.13+"); }
}
else
{ skip( 2 => "cannot find $file"); }
}
{
my $file= File::Spec->catfile( $Bin, "test_new_features_3_22.xml");
if( -f $file)
{ XML::Twig::_disallow_use( 'LWP::Simple');
eval { XML::Twig->nparse( "file://$file"); };
matches( $@, "^missing LWP::Simple", "nparse url without LWP::Simple");
XML::Twig::_allow_use( 'LWP::Simple');
if( perl_io_layer_used())
{ skip( 1 => "cannot test url parsing when UTF8 perlIO layer used"); }
elsif( XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent'))
{ my $url= "file://$file";
$url=~ s{\\}{/}g; # we need a URL, not a file name
if( LWP::Simple::get( $url))
{ my $content= XML::Twig->nparse( $url)->sprint;
is( $content, " ", "nparse url (nothing there)");
}
else
{ skip( 1 => "it looks like your LWP::Simple's get cannot handle '$url'"); }
}
else
{ skip( 1 => "cannot test url parsing without LWP"); }
}
else
{ skip( 2 => "cannot find $file"); }
}
{ my $file= File::Spec->catfile( "t", "test_new_features_3_22.xml");
open( FH, "<$file") or die "cannot find test file '$file': $!";
my $content= XML::Twig->nparse( \*FH)->sprint;
is( $content, " ", "nparse glob");
}
XML-Twig-3.50/t/test2_2.res 0000644 0001750 0001750 00000002322 12637027414 015520 0 ustar mrodrigu mrodrigu
]>
S1 I1 S1 I2 S1 Title S1 P1 S2 P2 Note P1 S1 para 3 S2 intro S2 Title S2 P1 S2 P2 S2 P3 Annex Title Annex P1 Annex P2