XML-Twig-3.50/0000755000175000017500000000000012637027512013260 5ustar mrodrigumrodriguXML-Twig-3.50/MANIFEST0000644000175000017500000002021012637027273014410 0ustar mrodrigumrodriguMANIFEST 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/0000755000175000017500000000000012637027512013523 5ustar mrodrigumrodriguXML-Twig-3.50/t/test4.t0000755000175000017500000001414612346001774014763 0ustar mrodrigumrodrigu#!/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='
Title <b>bold</b>

para1

para2

Title

para2

para3

'; 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, '

para2

para3

', "sprint purged doc"); $t= new XML::Twig( TwigRoots => { title => 1}); $t->parse( $s); my $doc= $t->sprint; stest( $doc, 'Title <b>bold</b>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 <b>bold</b>Title', "using title as TwigRoots (with doc handler)"); $s='
t1 <b>b1</b>

para1

ts1 <b>b2</b> para1

para2

t2

para3

para4
ts2

para6

para7

'; $t= new XML::Twig( TwigHandlers => { doc => sub { $_[1]->set_att( mod => "yes"); } }, TwigRoots => { title => 1}); $t->parse( $s); $doc= $t->sprint; stest( $doc, 't1 <b>b1</b>ts1 <b>b2</b>t2ts2', "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 <b>b1</b>ts1 <b>b2</b>para1t2para4ts2', "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.t0000755000175000017500000001417312346001775017756 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000130312346001775020672 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000102712346001775020131 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000663612346001774015433 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000234212346001775020145 0ustar mrodrigumrodrigu#!/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{foobar}; 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.t0000755000175000017500000001576512346001775020207 0ustar mrodrigumrodrigu#!/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{t1t2}; 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{t1t2}; 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{foobarfoobar}; 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{totototo}, "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{totototo}, "set_text"); } XML-Twig-3.50/t/test_bugs_3_22.t0000755000175000017500000005170312346001774016444 0ustar mrodrigumrodrigu#!/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

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{okNOK}; my $expected= q{okNOK}; 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.t0000755000175000017500000001070612346001774015541 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000102612346001775017061 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000004732012346001774014764 0ustar mrodrigumrodrigu#!/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= '

'. 'sub5sub3sub5 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= '

'. 'sub5sub3sub5 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= '

'. 'sub5sub3sub5 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= '

'. 'sub5sub3sub5 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= '

'. 'sub5sub3sub5 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='text1root1text 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.xml0000644000175000017500000000257312346001775015535 0ustar mrodrigumrodrigu ]>
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.t0000755000175000017500000000061712346001775020610 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000067412346001774022012 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000035212712346001775017074 0ustar mrodrigumrodrigu#!/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( 'foobaz'); 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, 'barfoo', "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 textelt3 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( 'val1val2'); 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, 'val1new 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 3elt 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 3elt 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_2e2_3 e2_4e2_5e3_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 2val 3val 1',# test 182 "insert 3 elements"); $t->root->sort_children_on_value; is( $t->sprint, 'val 1val 2val 3',# test 183 "sort_children_on_value"); $t->root->sort_children_on_att( "att", order => "reverse" ); is( $t->sprint, 'val 1val 3val 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, '

fini

', "split");# test 187 $alt1_p->first_child->split( qr/(i)/, 'b' ); is( $alt1_p->sprint, '

fini

', "split");# test 188 $new_p->split( qr/(i)/, b => { foo => "bar" } ); is( $new_p->sprint, '

fini

', "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, 'tooto', "replace_with");# test 215 $o->new( t => {a => 1 }, 'ta')->paste_within( $t->first_elt( 'b')->first_child, 1); is( $t->sprint, 'totaoto', "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( 'foototototobar'); is( $t->sprint, "foototo", "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, 'textxxmore textxxend', 'mark');# test 275 $alt_root->first_child->mark( ' (xx) ', b => { att => "y" }); is( $alt_root->sprint, 'textxxmore textxxend', '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( ' 03val 1 2val 2 4val 3 01val 4 05 '); $t->root->sort_children_on_field( 'key', type =>'numeric' ); my $expected= ' 01val 4 2val 2 03val 1 4val 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( ' 03val 1 2val 2 4val 3 01val 4 '); $t->root->sort_children_on_field( 'key', type =>'numeric' ); my $expected= ' 01val 4 2val 2 03val 1 4val 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 2e 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{beforefinish}); 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 textt

[
}; 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= ' foobarfoono '; 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 1pr', 'asis'); is( $ne->sprint, 'p 1pr', 'prefix asis');# test 457 $ne->prefix( 'p 2', 'asis'); is( $ne->sprint, 'p 2p 1pr', 'prefix asis');# test 458 $ne->suffix( 's 1su', 'asis'); is( $ne->sprint, 'p 2p 1prs 1su', 'prefix asis');# test 459 $ne->suffix( 's 2', 'asis'); is( $ne->sprint, 'p 2p 1prs 1sus 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{totototo totototo }; 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{totototo totototo totototo }; 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{totototo totototo totototo }; 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{totototo totototo totototo }; 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{totototo totototo totototo }; 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{123 113 121 }; 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{123 113 121 }; 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, 'toto', '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

t

i

', "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{val1val2}; 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 1text 2text 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 1new 2new 3', 'replace');# test 576 $new1->replace_with( $elt2, $elt1, $elt3); is( $t->sprint, 'text 2text 1text 3new 2new 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=< textthis
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='texttext'; $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, 'texttext',# 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, 'texttext',# 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 1text 2}; my $expected_s1= q{ text 1 text 2 }; my $expected_s2= q{text 1text 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{tatakaboom}; 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.t0000755000175000017500000001060312346001774016261 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000000102312346001774020137 0ustar mrodrigumrodrigu#!/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.t0000755000175000017500000001421012346001775020164 0ustar mrodrigumrodrigu#!/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{Tt
t2

t3}; my $expected= HTML::TreeBuilder->new->parse( $html)->as_XML; $expected=~ s{>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}g; $expected=~s{

t3}{

t3

}; $expected=~ s{> "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.res0000644000175000017500000000232212637027414015520 0ustar mrodrigumrodrigu ]>
S1 I1S1 I2S1 TitleS1 P1S2 P2Note P1S1 para 3
S2 introS2 TitleS2 P1S2 P2S2 P3
Annex TitleAnnex P1Annex P2
XML-Twig-3.50/t/xmlxpath_23func.t0000755000175000017500000000143512346001775016743 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//BBB[position() mod 2 = 0 ]'); ok(@nodes, 4); @nodes = $t->findnodes('//BBB [ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]'); ok(@nodes, 2); @nodes = $t->findnodes('//CCC [ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]'); ok(@nodes, 1); exit 0; __DATA__ XML-Twig-3.50/t/test_3_42.t0000755000175000017500000000165012346001775015423 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 3; { my $t= XML::Twig->new( twig_handlers => { e => sub { XML::Twig::Elt->parse( '')->paste( before => $_); } }) ->parse(''); is( $t->sprint, '', 'elements created with parse are still available once parsing is done'); } import myElt; { my $doc='fooe1e2foo'; my $t= XML::Twig->new( elt_class => 'myElt', field_accessors => { e => 'e' }, elt_accessors => { ee => 'e', ef => 'f', }, ) ->parse( $doc); is( join( ':', map { $_->e } $t->root->ef), 'e1:e2', 'elt_accessors with elt_class'); is( join( ':', map { $_->ee->text } $t->root->children( 'f')), 'e1:e2', 'field_accessors with elt_class'); } package myElt; use base 'XML::Twig::Elt'; 1; XML-Twig-3.50/t/xmlxpath_22name_select.t0000755000175000017500000000064712346001774020271 0ustar mrodrigumrodrigu#!/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( '//*[name() = /AAA/SELECT]'); ok(@nodes, 2); ok($nodes[0]->getName, "BBB"); exit 0; __DATA__ XML-Twig-3.50/t/test_xml_split/0000755000175000017500000000000012637027512016575 5ustar mrodrigumrodriguXML-Twig-3.50/t/test_xml_split/test_xml_split_expected-12-01.xml0000644000175000017500000000065512637027435024722 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-03.xml0000644000175000017500000000003312637027431024624 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-04.xml0000644000175000017500000000012012637027434024705 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-11-01.xml0000644000175000017500000000065512637027434024720 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-05.xml0000644000175000017500000000003312637027432024631 0ustar mrodrigumrodriguelt1 content 5XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-04.xml0000644000175000017500000000003312637027432024631 0ustar mrodrigumrodriguelt1 content 4XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-13-01.xml0000644000175000017500000000005712637027435024717 0ustar mrodrigumrodrigutext with < > & and 'XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-8-02.xml0000644000175000017500000000005612346001775024637 0ustar mrodrigumrodrigu & and ']]> XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-04.xml0000644000175000017500000000012012637027434024635 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-6-01.xml0000644000175000017500000000012012637027433024626 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-06.xml0000644000175000017500000000003312637027432024633 0ustar mrodrigumrodriguelt1 content 6XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-5-01.xml0000644000175000017500000000012012637027432024624 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-00.xml0000644000175000017500000000123212637027432024627 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-01.xml0000644000175000017500000000003312637027434024635 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-02.xml0000644000175000017500000000006112637027436024720 0ustar mrodrigumrodrigu elt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-00.xml0000644000175000017500000000056212637027437024727 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-5-00.xml0000644000175000017500000000035512637027432024635 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-11-00.xml0000644000175000017500000000012012637027434024702 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-09.xml0000644000175000017500000000003312637027432024636 0ustar mrodrigumrodriguelt1 content 9XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-7-02.xml0000644000175000017500000000005612346001775024636 0ustar mrodrigumrodrigu & and ']]> XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-14-02.xml0000644000175000017500000000005512346001775024713 0ustar mrodrigumrodrigu & and ']]>XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-7-00.xml0000644000175000017500000000011612637027433024633 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-15-01.xml0000644000175000017500000000005712637027436024722 0ustar mrodrigumrodrigutext with < > & and 'XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-12-00.xml0000644000175000017500000000011712637027435024712 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-00.xml0000644000175000017500000000052712637027434024644 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-13-02.xml0000644000175000017500000000005512637027435024716 0ustar mrodrigumrodrigu & and ']]>XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-02.xml0000644000175000017500000000003312637027432024627 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-04.xml0000644000175000017500000000006112637027436024722 0ustar mrodrigumrodrigu elt1 content 4XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-03.xml0000644000175000017500000000003312637027432024627 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-01.xml0000644000175000017500000000006112637027437024722 0ustar mrodrigumrodrigu elt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-04.xml0000644000175000017500000000003312637027432024630 0ustar mrodrigumrodriguelt1 content 4XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-18-00.xml0000644000175000017500000000035312637027437024724 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-03.xml0000644000175000017500000000003312637027431024625 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-05.xml0000644000175000017500000000025312637027431024632 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-01.xml0000644000175000017500000000003312637027434024705 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-02.xml0000644000175000017500000000006112637027437024723 0ustar mrodrigumrodrigu elt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-14-01.xml0000644000175000017500000000026612637027435024722 0ustar mrodrigumrodrigu text with < > & and ' & and ']]> XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-08.xml0000644000175000017500000000003312637027432024635 0ustar mrodrigumrodriguelt1 content 8XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-21-00.xml0000644000175000017500000000055712637027437024724 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-8-00.xml0000644000175000017500000000011512637027433024633 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-03.xml0000644000175000017500000000006112637027436024720 0ustar mrodrigumrodrigu elt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-00.xml0000644000175000017500000000052712637027431024631 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-03.xml0000644000175000017500000000003312637027432024630 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-09.xml0000644000175000017500000000003312637027432024635 0ustar mrodrigumrodriguelt1 content 9XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-7-01.xml0000644000175000017500000000065412637027433024643 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-02.xml0000644000175000017500000000003312637027434024636 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-03.xml0000644000175000017500000000006112637027436024721 0ustar mrodrigumrodrigu elt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-04.xml0000644000175000017500000000012012637027431024622 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-20-00.xml0000644000175000017500000000014512637027437024714 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-03.xml0000644000175000017500000000003312637027434024637 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-02.xml0000644000175000017500000000003312637027434024706 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-00.xml0000644000175000017500000000052712637027434024714 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-06.xml0000644000175000017500000000006112637027436024724 0ustar mrodrigumrodrigu elt1 content 6XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-6-03.xml0000644000175000017500000000022212637027433024633 0ustar mrodrigumrodrigu elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-02.xml0000644000175000017500000000006112637027436024717 0ustar mrodrigumrodrigu elt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-18-02.xml0000644000175000017500000000033112637027437024722 0ustar mrodrigumrodrigu elt1 content 3 elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-09.xml0000644000175000017500000000006112637027436024727 0ustar mrodrigumrodrigu elt1 content 9XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-01.xml0000644000175000017500000000003312637027432024626 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-02.xml0000644000175000017500000000003312637027432024626 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-18-03.xml0000644000175000017500000000042612637027437024730 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-01.xml0000644000175000017500000000006112637027436024717 0ustar mrodrigumrodrigu elt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-13-00.xml0000644000175000017500000000022712637027435024715 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-06.xml0000644000175000017500000000003312637027432024632 0ustar mrodrigumrodriguelt1 content 6XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-6-02.xml0000644000175000017500000000012612637027433024635 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-21-03.xml0000644000175000017500000000021012637027437024711 0ustar mrodrigumrodrigu elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-21-02.xml0000644000175000017500000000034112637027437024715 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-00.xml0000644000175000017500000000132412637027436024721 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-07.xml0000644000175000017500000000006112637027436024725 0ustar mrodrigumrodrigu elt1 content 7XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-20-01.xml0000644000175000017500000000070212637027437024714 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-01.xml0000644000175000017500000000006112637027436024716 0ustar mrodrigumrodrigu elt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-21-01.xml0000644000175000017500000000024612637027437024720 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-5-02.xml0000644000175000017500000000012612637027432024633 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-6-00.xml0000644000175000017500000000036312637027433024636 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-00.xml0000644000175000017500000000052212637027431024625 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-01.xml0000644000175000017500000000003312637027431024623 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-15-02.xml0000644000175000017500000000005512637027436024721 0ustar mrodrigumrodrigu & and ']]>XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-00.xml0000644000175000017500000000126512637027432024634 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-04.xml0000644000175000017500000000012012637027431024623 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-05.xml0000644000175000017500000000003312637027432024632 0ustar mrodrigumrodriguelt1 content 5XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-02.xml0000644000175000017500000000003312637027431024623 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-03.xml0000644000175000017500000000003312637027434024707 0ustar mrodrigumrodriguelt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-5-03.xml0000644000175000017500000000022512637027432024634 0ustar mrodrigumrodrigu elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-8-01.xml0000644000175000017500000000065412637027433024644 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-00.xml0000644000175000017500000000056212637027436024723 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-05.xml0000644000175000017500000000006112637027436024723 0ustar mrodrigumrodrigu elt1 content 5XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-17-08.xml0000644000175000017500000000006112637027436024726 0ustar mrodrigumrodrigu elt1 content 8XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-1-01.xml0000644000175000017500000000003312637027431024622 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-03.xml0000644000175000017500000000006112637027437024724 0ustar mrodrigumrodrigu elt1 content 3XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-9-05.xml0000644000175000017500000000025312637027434024645 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-07.xml0000644000175000017500000000003312637027432024633 0ustar mrodrigumrodriguelt1 content 7XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-02.xml0000644000175000017500000000003312637027431024624 0ustar mrodrigumrodriguelt1 content 2XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-05.xml0000644000175000017500000000030112637027436024717 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-04.xml0000644000175000017500000000014612637027437024731 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-2-05.xml0000644000175000017500000000025312637027431024633 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-4-07.xml0000644000175000017500000000003312637027432024634 0ustar mrodrigumrodriguelt1 content 7XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-16-04.xml0000644000175000017500000000014612637027436024725 0ustar mrodrigumrodrigu elt1 content 4 elt1 content 5 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-18-01.xml0000644000175000017500000000024412637027437024724 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-10-05.xml0000644000175000017500000000025312637027434024715 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-15-00.xml0000644000175000017500000000022712637027436024720 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-19-05.xml0000644000175000017500000000030112637027437024723 0ustar mrodrigumrodrigu elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-08.xml0000644000175000017500000000003312637027432024634 0ustar mrodrigumrodriguelt1 content 8XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-14-00.xml0000644000175000017500000000012212637027435024710 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_xml_split/test_xml_split_expected-3-01.xml0000644000175000017500000000003312637027432024625 0ustar mrodrigumrodriguelt1 content 1XML-Twig-3.50/t/test_3_47.t0000755000175000017500000000260212346001775015426 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 3; use utf8; # test CDATA sections in HTML escaping https://rt.cpan.org/Ticket/Display.html?id=86773 # module => XML::Twig->new options my %html_conv= ( 'HTML::TreeBuilder' => {}, 'HTML::Tidy' => { use_tidy => 1 }, ); foreach my $module ( sort keys %html_conv) { SKIP: { eval "use $module"; skip "$module not available", 1 if 1 ; my $in = q{

Here&there v&r;

marco&company; and marco&company £ £ £ £

}; my $expected= q{

Here&there v&r;

marco&company; and marco&company £ £ £ £

}; my $parser= XML::Twig->new( %{$html_conv{$module}}); my $t = $parser->safe_parse_html($in); print $@ if $@; like $t->sprint, qr{\Q$expected\E}, "In and out are the same ($module)"; } } { # test RT #94295 https://rt.cpan.org/Public/Bug/Display.html?id=94295 # in twig_handlers, '=' in regexps on attributes are turned into 'eq' my $xml= 'e1e2'; my $r; my $t= XML::Twig->new( twig_handlers => { 'e[@dn =~ /host=0/]' => sub { $r.= $_->text } }) ->parse( $xml); is( $r, 'e1', 'regexp on attribute, including an = sign'); } exit; XML-Twig-3.50/t/test_3_36.t0000755000175000017500000004060212346001775015426 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=67; print "1..$TMAX\n"; { my $doc=q{title 1title 2}; my $ids; XML::Twig->parse( twig_handlers => { 's[t]' => sub { $ids .= $_->id; } }, $doc); is( $ids, 's2s1', 's[t]'); } { my $string = q{power}; my $t=XML::Twig->parse( $string); my $root = $t->root(); my $copy = $root->copy(); is( $copy->sprint, $root->sprint, 'empty elements in a copy') } { my $doc=q{e1e2e3f1}; my $t=XML::Twig->parse( $doc); my $e1= $t->first_elt( 'e'); is( all_text( $e1->siblings), 'e2:e3:f1', 'siblings, all'); is( all_text( $e1->siblings( 'e')), 'e2:e3', 'siblings(e)'); is( all_text( $e1->siblings('f')), 'f1', 'siblings(f)'); my $e2= $e1->next_sibling( 'e'); is( all_text( $e2->siblings), 'e1:e3:f1', 'siblings (2cd elt), all'); is( all_text( $e2->siblings( 'e')), 'e1:e3', 'siblings(e) (2cd elt)'); is( all_text( $e2->siblings('f')), 'f1', 'siblings(f) (2cd elt)'); my $f= $e1->next_sibling( 'f'); is( all_text( $f->siblings), 'e1:e2:e3', 'siblings (f elt), all'); is( all_text( $f->siblings( 'e')), 'e1:e2:e3', 'siblings(e) (f elt)'); is( all_text( $f->siblings('f')), '', 'siblings(f) (f elt)'); } { my $doc= q{barbar2ff1}; my $t= XML::Twig->new( att_accessors => [ 'b', 'a' ], elt_accessors => [ 'x', 'e', 'f' ], field_accessors => [ 'f3', 'f1' ]) ->parse( $doc); my $d= $t->root; is( $d->e->a, 'foo', 'accessors (elt + att)'); is( $d->f->a, 'foo2', 'accessors (elt + att), on f'); is( $d->f1, 'ff1', 'field accessor'); eval { $t->elt_accessors( 'tag'); }; matches( $@, q{^attempt to redefine existing method tag using elt_accessors }, 'duplicate elt accessor'); eval { $t->field_accessors( 'tag'); }; matches( $@, q{^attempt to redefine existing method tag using field_accessors }, 'duplicate elt accessor'); $t->att_accessors( 'a2'); is( $d->f->a2, 'toto', 'accessors created after the parse'); $t->elt_accessors( 'f'); $t->att_accessors( 'a2'); is( $d->f->a2, 'toto', 'accessors created twice after the parse'); $t->field_accessors( 'f1'); is( $d->f1, 'ff1', 'field accessor (created twice)'); } { my $doc=q{foobarvaztoto}; my $t= XML::Twig->parse( $doc); $t->elt_id( 'i1')->set_outer_xml( 'boh'); $t->elt_id( 'i3')->set_outer_xml( 'duh'); is( $t->sprint, 'bohbarduh', 'set_outer_xml'); } { my $doc= q{}; my $t= XML::Twig->parse( $doc); $t->first_elt( 'e')->cut_children( 'g'); is( $t->sprint, q{}, "cut_children leaves some children"); } { if( $] >= 5.006) { my $t= XML::Twig->parse( q{}); $t->first_elt( 'e')->latt( 'a')= 'b'; is( $t->sprint, q{}, 'lvalued attribute (no attributes)'); $t->first_elt( 'e')->latt( 'c')= 'd'; is( $t->sprint, q{}, 'lvalued attribute (attributes)'); $t->first_elt( 'e')->latt( 'c')= ''; is( $t->sprint, q{}, 'lvalued attribute (modifying existing attributes)'); $t->root->lclass= 'foo'; is( $t->sprint, q{}, 'lvalued class (new class)'); $t->root->lclass=~ s{fo}{tot}; is( $t->sprint, q{}, 'lvalued class (modify class)'); $t= XML::Twig->parse( ''); $t->root->latt( 'a')++; is( $t->sprint, '', '++ on attribute'); } else { skip( 6 => "cannot use lvalued attributes with perl $]"); } } # used for all HTML parsing tests with HTML::Tidy my $DECL= qq{\n}; my $NS= 'xmlns="http://www.w3.org/1999/xhtml"'; { # testing set_inner_html if( !XML::Twig::_use( 'HTML::Tidy')) { skip( 4 => "need HTML::Tidy to use the use_tidy method method"); } elsif( !XML::Twig::_use( 'LWP')) { skip( 4 => "need LWP to use set_inner_html method"); } elsif( !XML::Twig::_use( 'HTML::TreeBuilder')) { skip( 4 => "need LWP to use set_inner_html method"); } else { my $doc= 'a titlepar 1

par 2
after the break'; my $t= XML::Twig->new( use_tidy => 1)->parse_html( $doc); my $inner= '

  • foo
  • bar
'; $t->first_elt( 'p')->set_inner_html( $inner); (my $expected= $t->sprint)=~ s{

.*

}{

$inner

}; is( $t->sprint, $expected, "set_inner_html"); $inner= q{2cd title}; $t->first_elt( 'head')->set_inner_html( $inner); $inner=~ s{>$}{/>}; $expected=~ s{.*}{$inner}; $expected=~ s{(]*)(/>)}{$1 $2}g; is( $t->sprint, $expected, "set_inner_html (in head)"); $inner= q{

just a p

}; $t->root->set_inner_html( $inner); $expected= qq{$DECL$inner}; is( $t->sprint, $expected, "set_inner_html (all doc)"); $inner= q{the content of the
body}; $t->first_elt( 'body')->set_inner_html( $inner); $expected= qq{$DECL$inner}; $expected=~ s{
}{
}g; is( $t->sprint, $expected, "set_inner_html (body)"); } } { if( !XML::Twig::_use( "File::Temp")) { skip( 5, "File::Temp not available"); } elsif( !XML::Twig::_use( "HTML::Tidy")) { skip( 5, "HTML::Tidy not available"); } elsif( !XML::Twig::_use( "LWP")) { skip( 5, "LWP not available"); } elsif( !XML::Twig::_use( "LWP::UserAgent")) { skip( 5, "LWP::UserAgent not available"); } else { # parsefile_html_inplace my $file= "test_3_36.html"; spit( $file, q{foo

this is it

>}); XML::Twig->new( use_tidy => 1, twig_handlers => { p => sub { $_->set_tag( 'h1')->flush; }}) ->parsefile_html_inplace( $file); matches( slurp( $file), qr/

/, "parsefile_html_inplace"); XML::Twig->new( use_tidy => 1, twig_handlers => { h1 => sub { $_->set_tag( 'blockquote')->flush; }}, error_context => 6) ->parsefile_html_inplace( $file, '.bak'); matches( slurp( $file), qr/
/, "parsefile_html_inplace (with backup, checking file)"); matches( slurp( "$file.bak"), qr/

/, "parsefile_html_inplace (with backup, checking backup)"); unlink( "$file.bak"); XML::Twig->new( use_tidy => 1, twig_handlers => { blockquote => sub { $_->set_tag( 'div')->flush; }}) ->parsefile_html_inplace( $file, 'bak_*'); matches( slurp( $file), qr/
/, "parsefile_html_inplace (with complex backup, checking file)"); matches( slurp( "bak_$file"), qr/
/, "parsefile_html_inplace (with complex backup, checking backup)"); unlink( "bak_$file"); unlink $file; } } { if( _use( 'HTML::Tidy')) { XML::Twig->set_pretty_print( 'none'); my $html=q{

Title

foo
bar

}; my $expected= qq{$DECL

Title

foo
\nbar

}; is( XML::Twig->new( use_tidy => 1 )->safe_parse_html( $html)->sprint, $expected, 'safe_parse_html'); my $html_file= "t/test_3_30.html"; spit( $html_file, $html); is( XML::Twig->new( use_tidy => 1 )->safe_parsefile_html( $html_file)->sprint, $expected, 'safe_parsefile_html'); if( _use( 'LWP')) { is( XML::Twig->new( use_tidy => 1 )->safe_parseurl_html( "file:$html_file")->sprint, $expected, 'safe_parseurl_html'); } else { skip( 1, "LWP not available, cannot test safe_parseurl_html"); } unlink $html_file; } else { skip( 3, "HTML::Tidy not available, cannot test safe_parse.*_html methods with the use_tidy option"); } } { # testing parse_html with use_tidy if( XML::Twig::_use( 'HTML::Tidy') && XML::Twig::_use( 'LWP::Simple') && XML::Twig::_use( 'LWP::UserAgent')) { my $html= q{Tt
t2

t3}; my $tidy= HTML::Tidy->new( { output_xhtml => 1, # duh! tidy_mark => 0, # do not add the "generated by tidy" comment numeric_entities => 1, char_encoding => 'utf8', bare => 1, clean => 1, doctype => 'transitional', fix_backslash => 1, merge_divs => 0, merge_spans => 0, sort_attributes => 'alpha', indent => 0, wrap => 0, break_before_br => 0 } ); $tidy->ignore( type =>1, type => 2); my $expected= $tidy->clean( $html); $expected=~ s{>new( use_tidy => 1)->parse_html( $html)->sprint, $expected, 'parse_html string using HTML::Tidy'); 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( use_tidy => 1)->parsefile_html( $html_file)->sprint, $expected, 'parsefile_html using HTML::Tidy'); open( HTML, "<$html_file") or die "cannot open HTML file '$html_file': $!"; is_like( XML::Twig->new( use_tidy => 1)->parse_html( \*HTML)->sprint, $expected, 'parse_html fh using HTML::Tidy'); } else { skip( 2, "could not write HTML file in t directory, check permissions"); } } else { skip( 3 => 'need HTML::Tidy and LWP to test parse_html with the use_tidy option'); } } { if( XML::Twig::_use( 'HTML::TreeBuilder')) { my $html_with_Amp= XML::Twig->new->parse_html( '&Amp;')->sprint; if( $HTML::TreeBuilder::VERSION <= 3.23) { is( $html_with_Amp, '&', '&Amp; used in html (fixed HTB < 4.00)'); } else { is( $html_with_Amp, '&Amp;', '&Amp; used in html (NOT fixed HTB > r.00)'); } is( XML::Twig->new->parse_html( '')->sprint, '', 'extra XML declaration in html' ); my $doc=q{

fooah

}; (my $expected= $doc)=~s{

}{

}g; is_like( XML::Twig->parse($doc)->sprint, $expected, 'CDATA and comments in html'); } else { skip( 3, 'need HTML::TreeBuilder for additional HTML tests'); } } { my $t= XML::Twig->parse( ''); $t->{twig_root}= undef; is( $t->first_elt, undef, 'first_elt on empty tree'); is( $t->last_elt, undef, 'last_elt on empty tree'); } { if( XML::Twig::_use( 'XML::XPathEngine') && XML::Twig::_use( 'XML::Twig::XPath')) { my $t= XML::Twig::XPath->new->parse( '

'); eval { $t->get_xpath( '//d[.//p]'); }; matches( $@, qr{the expression is a valid XPath statement, and you are using XML::Twig::XPath}, 'non XML::Twig xpath with get_xpath'); } else { skip( 1); } } { my $r= XML::Twig->parse( '')->root; is( $r->is_empty, 0, 'non empty element'); $r->cut_children( 'e'); is( $r->is_empty, 0, 'non empty element after cut_children'); $r->cut_children( 'e1'); is( $r->is_empty, 1, 'empty element after cut_children'); } { my $r= XML::Twig->parse( '')->root; is( $r->is_empty, 0, 'non empty element'); $r->cut_descendants( 'e'); is( $r->is_empty, 0, 'non empty element after cut_descendants'); $r->cut_descendants( 'e1'); is( $r->is_empty, 1, 'empty element after cut_descendants'); } { if( XML::Twig::_use( 'LWP::Simple')) { eval { XML::Twig->parse( 'file://not_there'); }; matches( $@, 'no element found', 'making xparse fail'); } else { skip( 1); } } { is( XML::Twig::Elt::_short_text( 'a', 0), 'a', 'shorten with no length'); } { is( XML::Twig->parse( comments => 'process', pi => 'process', pretty_print => 'indented', "" )->sprint, "\n \n \n \n \n \n \n \n \n\n", 'indenting pi and comments' ); } { XML::Twig::_set_debug_handler(3); XML::Twig->new( twig_handlers => { 'foo[@a="bar"]' => sub { $_->att( 'a')++; } }); my $expected=<<'EXPECTED'; parsing path 'foo[@a="bar"]' predicate is: '@a="bar"' predicate becomes: '$elt->{'a'} eq "bar"' perlfunc: no warnings; my( $stack)= @_; my @current_elts= (scalar @$stack); my @new_current_elts; my $elt; warn q{checking path 'foo[@a="bar"]' }; foreach my $current_elt (@current_elts) { next if( !$current_elt); $current_elt--; $elt= $stack->[$current_elt]; if( ($elt->{'##tag'} eq "foo") && $elt->{'a'} eq "bar") { push @new_current_elts, $current_elt;} } unless( @new_current_elts) { warn qq%fail at cond '($elt->{'##tag'} eq "foo") && $elt->{'a'} eq "bar"'%; return 0; } @current_elts= @new_current_elts; @new_current_elts=(); warn "handler for 'foo[@a="bar"]' triggered\n"; return q{foo[@a="bar"]}; last tag: 'foo', test_on_text: '0' score: anchored: 0 predicates: 3 steps: 1 type: 3 EXPECTED my $got= XML::Twig::_return_debug_handler(); $got=~ s{\\}{}g; $expected=~ s{\\}{}g; is( $got, $expected, 'handler content'); XML::Twig::_set_debug_handler( 0); } { my $t=XML::Twig->parse( elt_class => 'XML::Twig::Elt', ''); is( ref($t->root), 'XML::Twig::Elt', 'alternate class... as the default one!'); } { my( $triggered_bare, $triggered_foo); my $t= XML::Twig->new( twig_handlers => { 'e1[@#a]' => sub { $triggered_bare.=$_->id; }, 'e1[@#a="foo"]' => sub { $triggered_foo .=$_->id; }, e2 => sub { $_->parent->set_att( '#a', 1); }, e4 => sub { $_->parent->set_att( '#a', 'foo'); }, } ) ->parse( ''); is( $triggered_bare, 'e1.1e1.2', 'handler condition on bare private attribute'); is( $triggered_foo , 'e1.1', 'handler condition on valued private attribute'); } { my $t= XML::Twig->parse( ''); $t->root->remove_class( 'foo'); is( $t->root->class, '', 'empty class after remove_class'); my $e= $t->first_elt( 'e'); $e->remove_class( 'foo'); is( $e->class, 'bar baz', 'remove_class on non-existent class'); $e->remove_class( 'baz'); is( $e->class, 'bar', 'remove_class'); $e->remove_class( 'foo'); is( $e->class, 'bar', 'remove_class on non-existent class (again)'); $e->remove_class( 'bar'); is( $e->class, '', 'remove_class until no class is left'); } { if( XML::Twig::_use( 'Text::Wrap')) { my $out= "t/test_wrapped.xml"; my $out_fh; open( $out_fh, ">$out") or die "cannot create temp file $out: $!"; $Text::Wrap::columns=40; $Text::Wrap::columns=40; XML::Twig->parse( pretty_print => 'wrapped', '' . "foobarbaz " x 10 . '') ->print( $out_fh); close $out_fh; is( slurp( $out),qq{\n foobarbaz foobarbaz foobarbaz\n foobarbaz foobarbaz foobarbaz\n foobarbaz foobarbaz foobarbaz\n foobarbaz \n}, 'wrapped print' ); unlink $out; } else { skip( 1); } } sub all_text { return join ':' => map { $_->text } @_; } 1; XML-Twig-3.50/t/xmlxpath_06attrib_val.t0000755000175000017500000000102112346001774020126 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//BBB[@id = "b1"]'); ok(@nodes, 1); @nodes = $t->findnodes( '//BBB[@name = "bbb"]'); ok(@nodes, 1); @nodes = $t->findnodes( '//BBB[normalize-space(@name) = "bbb"]'); ok(@nodes, 2); exit 0; __DATA__ XML-Twig-3.50/t/test_variables.t0000755000175000017500000000263512346001774016727 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; print "1..6\n"; #warn "\n\n### warnings are normal here ###\n\n"; my $t= XML::Twig->new->parse( \*DATA); # intercept warnings $SIG{__WARN__} = sub { print STDERR @_ if( $_[0]=~ /^test/); }; my $s= $t->simplify( var_attr => 'var', variables => { 'v2' => 'elt2'}); if( $s->{elt2} eq 'elt using elt1') { print "ok 1\n" } else { print "not ok 1\n"; warn "test 1: /$s->{elt2}/ instead of 'elt using elt1'\n"; } if( $s->{elt3} eq 'elt using elt1') { print "ok 2\n" } else { print "not ok 2\n"; warn "test 2: /$s->{elt3}/ instead of 'elt using elt1'\n"; } if( $s->{elt4} eq 'elt using elt2') { print "ok 3\n"; warn "\n"; } else { print "not ok 3\n"; warn "test 3: /$s->{elt4}/ instead of 'elt using elt2'\n"; } if( $s->{elt5}->{att1} eq 'att with elt1') { print "ok 4\n" } else { print "not ok 4\n"; warn "test 4: /$s->{elt5}->{att1}/ instead of 'att with elt1'\n"; } $s= $t->simplify( variables => { 'v2' => 'elt2'}); if( $s->{elt2} eq 'elt using $v1') { print "ok 5\n" } else { print "not ok 5\n"; warn "test 5: /$s->{elt2}/ instead of 'elt using \$v1'\n"; } if( $s->{elt4} eq 'elt using elt2') { print "ok 6\n" } else { print "not ok 6\n"; warn "test 6: /$s->{elt4}/ instead of 'elt using elt2'\n"; } exit 0; __DATA__ elt1 elt using $v1 elt using ${v1} elt using $v2 XML-Twig-3.50/t/xmlxpath_14axisancestor.t0000755000175000017500000000105412346001774020507 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '/AAA/BBB/DDD/CCC/EEE/ancestor::*'); ok(@nodes, 4); ok($nodes[1]->getName, "BBB"); # test document order @nodes = $t->findnodes( '//FFF/ancestor::*'); ok(@nodes, 5); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_25scope.t0000755000175000017500000000064312346001775017123 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 4); use XML::Twig::XPath; ok(1); eval { # Removing the 'my' makes this work?!? my $t= XML::Twig::XPath->new->parse( ''); ok( $t); $t->findnodes( '/test'); ok(1); die "This should be caught\n"; }; if ($@) { ok(1); } else { ok(0); } exit 0; XML-Twig-3.50/t/test_3_38.t0000755000175000017500000000666412346001774015441 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=21; print "1..$TMAX\n"; my $d= ''; { my $r= XML::Twig->parse( $d)->root; my $result = $r->att('a'); is( $r->sprint, $d, 'att'); } { my $r= XML::Twig->parse( $d)->root; my $result = foo($r->att('a')); is( $r->sprint, $d, 'att in sub(1)'); } { my $r= XML::Twig->parse( $d)->root; my $result = sub { return @_ }->($r->att('a')); is( $r->sprint, $d, 'att in anonymous sub'); } { my $r= XML::Twig->parse( $d)->root; my $a= $r->att( 'a'); is( $r->sprint, $d, 'att in scalar context'); } { my $r= XML::Twig->parse( $d)->root; my( $a1, $a2)= ($r->att( 'a1'), $r->att( 'a2')); is( $r->sprint, $d, 'att in list context'); } { my $r= XML::Twig->parse( $d)->root; $r->att( 'a'); is( $r->sprint, $d, 'att in void context'); } { my $r= XML::Twig->parse( $d)->root; my $result = $r->att('a'); is( $r->sprint, $d, 'att'); } { my $r= XML::Twig->parse( $d)->root; my $result = foo($r->class); is( $r->sprint, $d, 'class in sub(1)'); } { my $r= XML::Twig->parse( $d)->root; my $result = sub { return @_ }->($r->class); is( $r->sprint, $d, 'att in anonymous sub'); } { my $r= XML::Twig->parse( $d)->root; my $a= $r->class; is( $r->sprint, $d, 'class in scalar context'); } { my $r= XML::Twig->parse( $d)->root; my( $a1, $a2)= ($r->class, $r->class); is( $r->sprint, $d, 'class in list context'); } { my $r= XML::Twig->parse( $d)->root; $r->class; is( $r->sprint, $d, 'class in void context'); } { my $t= XML::Twig->new->parse( ''); $t->root->latt( 'a')= 1; is( $t->sprint, '', 'latt'); } { my $r= XML::Twig->parse( $d)->root; my $att= $r->att( 'foo'); is( $att, undef, 'unexisting att'); } # my $value = $root->att('any_attribute'); # $result = length($value); sub foo { return @_; } { my $r; my $doc='<_e id="e1"><_e id="e2"><_foo a="2" id="foo"/>'; my $t= XML::Twig->new( twig_handlers => { _e => sub { $r.= $_->id } }) ->parse( $doc); is( $r, 'e1e2', 'handler, condition on tag starting with an underscore'); is( $t->first_elt( '_foo')->id, 'foo', 'navigation, element name starts with underscore'); is( $t->first_elt( '*[@_a="2"]')->id, 'bar', 'navigation, attribute name starts with underscore'); } { if( _use( 'LWP') && _use( 'HTML::TreeBuilder') ) { my $html=q{

Title

foo
bar

}; my $expected= qq{

Title

foo
bar

}; my $html_file= "t/test_3_38.html"; spit( $html_file, $html); is( scrub_xhtml( XML::Twig->new( )->parseurl_html( "file:$html_file")->sprint), $expected, 'parseurl_html'); unlink $html_file; } else { skip( 1, "LWP and/or HTML::TreeBuilder not available, cannot test safe_parseurl_html"); } } { my $doc=" foo bar baz"; is( XML::Twig->parse( $doc)->simplify( normalize_space => 2)->{e}, 'foo bar baz', 'simplify with normalize_space => 2'); } { my $doc="foo bar foofoo foobar totofoo"; my $t= XML::Twig->parse( $doc); is( $t->subs_text( qr/(f)o(o)/, '&elt(b => $1) $2')->sprint, 'f o bar f of o f obar totof o', 'complex subs_text'); } { my $t= XML::Twig->parse( 'e1e2'); is( join( '-', $t->findvalues( '//e')), 'e1-e2', 'findvalues'); } 1; XML-Twig-3.50/t/test_expand_external_entities.xml0000644000175000017500000000015512346001775022372 0ustar mrodrigumrodrigu

&ent1;

&ent2;

more &ent1;

XML-Twig-3.50/t/test_pi_handler.t0000755000175000017500000000343312346001775017062 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; # test for the various conditions in navigation methods $|=1; use XML::Twig; if( $] < 5.008) { warn "skipped, not tested under perl < 5.8\n"; print "1..1\nok 1\n"; exit 0; } my $nb_tests=4; print "1..$nb_tests\n"; my $result; my $t= XML::Twig->new( pi => 'process', twig_handlers => { '?pi' => sub { $result .=$_->text; } }, ); $t->parse( q{}); my $expected= ''; if( $result eq $expected) { print "ok 1\n"; } else { print "not ok 1\n"; warn "expected: $expected\nfound : $result\n"; } $result=''; $t= XML::Twig->new( pi => 'process', twig_handlers => { '?pi' => sub { $result .=$_->text; } }, ); $t->parse( q{}); $expected= ''; if( $result eq $expected) { print "ok 2\n"; } else { print "not ok 2\n"; warn "expected: $expected\nfound : $result\n"; } $result=''; $t= XML::Twig->new( twig_handlers => { 'doc' => sub { $result= $_->{extra_data}; } },); $t->parse( q{}); $expected= ''; if( $result eq $expected) { print "ok 3\n"; } else { print "not ok 3\n"; warn "expected: $expected\nfound : $result\n"; } $result=''; $t= XML::Twig->new( pi => 'process', twig_roots => { '?pi' => sub { $result= $_->target . "/" . $_->data; }, elt => sub { }, }); $t->parse( q{}); $expected= 'pi/pi in doc '; if( $result eq $expected) { print "ok 4\n"; } else { print "not ok 4\n"; warn "expected: /$expected/\nfound : /$result/\n"; } exit 0; XML-Twig-3.50/t/test_ignore_elts.t0000755000175000017500000000446112346001775017271 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; my $TMAX=1; # do not forget to update! print "1..$TMAX\n"; my $doc= read_data(); my $t= XML::Twig->new( ignore_elts => { ignore => 1 }, keep_spaces => 1, ); my $result_file= "test_ignore_elt.res1"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; select RESULT; $t->parse( $doc); $t->print; select STDOUT; close RESULT; check_result( $result_file, 1); exit 0; # Not yet implemented # test 2 $doc= read_data(); $t= XML::Twig->new( ignore_elts => { ignore => 'print' }, twig_handlers => { elt => sub { $_->print; } }, keep_spaces => 1, ); $result_file= "test_ignore_elt.res2"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; select RESULT; $t->parse( $doc); $t->print; select STDOUT; close RESULT; check_result( $result_file, 2); sub read_data { local $/="\n\n"; my $data= ; $data=~ s{^\s*#.*\n}{}m; # get rid of comments $data=~ s{\s*$}{}s; # remove trailing spaces (and \n) $data=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines return $data; }; sub check_result { my( $result_file, $test_no)= @_; # now check result my $expected_result= read_data(); my $result= read_result( $result_file); if( $result eq $expected_result) { print "ok $test_no\n"; } else { print "not ok $test_no\n"; print STDERR "\ntest $test_no:\n", "expected: \n$expected_result\n", "real: \n$result\n"; } } sub read_result { my $file= shift; local $/="\n"; open( RESULT, "<$file") or die "cannot read $file: $!"; my @result= grep {m/\S/} ; close RESULT; unlink $file; return join '', @result; } __DATA__ # doc 1 text text # expected result 1 #doc 2 text text # expected result 2 text text XML-Twig-3.50/t/pod.t0000755000175000017500000000047412346001774014501 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; if( ! $ENV{TEST_AUTHOR} ) { print "1..1\nok 1\n"; warn "Author test. Set \$ENV{TEST_AUTHOR} to a true value to run.\n"; exit; } eval "use Test::Pod 1.00"; if( $@) { print "1..1\nok 1\n"; warn "skipping, Test::Pod required\n"; } else { all_pod_files_ok( ); } exit 0; XML-Twig-3.50/t/test_need_use_bytes.t0000755000175000017500000000333212346001775017750 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # tests that require IO::Scalar to run 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; BEGIN { eval "use bytes"; if( $@) { print "1..1\nok 1\n"; warn "skipping, need to be able to use bytes\n"; exit; } } print "1..2\n"; my $text= "été"; my $text_safe= "été"; my $text_safe_hex= "été"; my $doc=qq{\n$text}; my $doc_safe=qq{\n$text_safe}; my $doc_safe_hex=qq{\n$text_safe_hex}; my $t= XML::Twig->new()->parse( $doc); if( $] == 5.008) { skip( 2); } else { $t->set_output_text_filter( sub { my $text= shift; use bytes; $text=~ s{([\xC0-\xDF].|[\xE0-\xEF]..|[\xF0-\xFF]...)} {XML::Twig::_XmlUtf8Decode($1)}egs; return $text; } ); is( $t->sprint, $doc_safe, 'safe with _XmlUtf8Decode'); # test 338 $t->set_output_text_filter( sub { my $text= shift; use bytes; $text=~ s{([\xC0-\xDF].|[\xE0-\xEF]..|[\xF0-\xFF]...)} {XML::Twig::_XmlUtf8Decode($1, 1)}egs; return $text; } ); is( $t->sprint, $doc_safe_hex, 'safe_hex with _XmlUtf8Decode'); # test 339 } exit 0; XML-Twig-3.50/t/test2_2.dtd0000644000175000017500000000066112346001774015504 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_erase.t0000755000175000017500000000365712346001774016063 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; my $TMAX=1; # do not forget to update! print "1..$TMAX\n"; undef $/; my $doc=; my $t= XML::Twig->new(keep_spaces => 1); $t->parse( $doc); foreach my $erase ($t->descendants( 'erase')) { $erase->erase; } my $result=$t->sprint; $result=~ s{\s*$}{}s; # remove trailing spaces (and \n) my $expected_result= $doc; $expected_result=~ s{}{}g; $expected_result=~ s{\s*$}{}s; # remove trailing spaces (and \n) if( $result eq $expected_result) { print "ok 1\n"; } else { print "not ok 1\n"; print STDERR "expected: \n$expected_result\n", "real: \n$result\n"; } exit 0; __DATA__ text text (1) text text (2) text (3) text text (4) text (5) text (6) text (7)text (8) text (9) text (10) text (11) text text (12) text (13)text (14) text (15) text (16) text (17)text (18) text (19) text (20)child/> text (21)child/> text (22) XML-Twig-3.50/t/test_safe_encode.t0000755000175000017500000000362112346001774017206 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; my $DEBUG=0; print "1..8\n"; if( $] >= 5.006) { eval "use utf8;"; } # suitable for perl 5.6.* my $doc=q{<élément att="été">été}; (my $safe_xml_doc= $doc)=~ s{é}{é}g; (my $safe_hex_doc= $doc)=~ s{é}{é}g; (my $text_safe_xml_doc= $doc)=~ s{été}{ét&233;}g; (my $text_safe_hex_doc= $doc)=~ s{é}{ét&xe9;}g; is( XML::Twig->new( output_filter => 'safe')->parse( $doc)->sprint, $safe_xml_doc, "output_filter => 'safe'"); is( XML::Twig->new( output_filter => 'safe_hex')->parse( $doc)->sprint, $safe_hex_doc, "output_filter => 'safe_hex'"); is( XML::Twig->new( output_text_filter => 'safe')->parse( $doc)->sprint, $safe_xml_doc, "output_text_filter => 'safe'"); is( XML::Twig->new( output_text_filter => 'safe_hex')->parse( $doc)->sprint, $safe_hex_doc, "output_text_filter => 'safe_hex'"); # suitable for 5.8.* and above (you can't have utf-8 hash keys before that) if( $] < 5.008) { skip( 4 => "cannot process utf-8 attribute names with a perl before 5.8"); } else { my $doc='<élément atté="été">été'; (my $safe_xml_doc= $doc)=~ s{é}{é}g; (my $safe_hex_doc= $doc)=~ s{é}{é}g; (my $text_safe_xml_doc= $doc)=~ s{été}{ét&233;}g; (my $text_safe_hex_doc= $doc)=~ s{é}{ét&xe9;}g; is( XML::Twig->new( output_filter => 'safe')->parse( $doc)->sprint, $safe_xml_doc, "output_filter => 'safe'"); is( XML::Twig->new( output_filter => 'safe_hex')->parse( $doc)->sprint, $safe_hex_doc, "output_filter => 'safe_hex'"); is( XML::Twig->new( output_text_filter => 'safe')->parse( $doc)->sprint, $safe_xml_doc, "output_text_filter => 'safe'"); is( XML::Twig->new( output_text_filter => 'safe_hex')->parse( $doc)->sprint, $safe_hex_doc, "output_text_filter => 'safe_hex'"); } XML-Twig-3.50/t/xmlxpath_04pos.t0000755000175000017500000000063312346001775016607 0ustar mrodrigumrodriguuse 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 $first = $t->findvalue( '/AAA/BBB[1]/@id'); ok($first, "first"); my $last = $t->findvalue( '/AAA/BBB[last()]/@id'); ok($last, "last"); exit 0; __DATA__ XML-Twig-3.50/t/test2_1.res0000644000175000017500000000232412637027414015521 0ustar mrodrigumrodrigu ]>
S1 I1S1 I2S1 TitleS1 P1S2 P2Note P1S1 para 3
S2 introS2 TitleS2 P1S2 P2S2 P3
Annex TitleAnnex P1Annex P2
XML-Twig-3.50/t/tools.pm0000644000175000017500000002655412414166110015224 0ustar mrodrigumrodrigu# $Id: /xmltwig/trunk/t/tools.pm 21 2006-09-12T17:31:19.157455Z mrodrigu $ use strict; use Config; use Carp; use vars qw/$TDEBUG $TFATAL/; BEGIN { if( grep { m{-[f]*[dv][f]*} } @ARGV) { $TDEBUG=1; warn "debug!\n"; } if( grep { m{-[dv]*f[dv]*\b} } @ARGV) { $TFATAL= 1; warn "fatal!\n";} } { my $test_nb; BEGIN { $test_nb=0; } sub is { my( $got, $expected, $message) = @_; $test_nb++; if( ( !defined( $expected) && !defined( $got) ) || ($expected eq $got) ) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; if( length( $expected) > 20) { warn "$message:\nexpected: '$expected'\ngot : '$got'\n"; } else { warn "$message: expected '$expected', got '$got'\n"; } croak if $TFATAL; return 0; } } sub isnt { my( $got, $expected, $message) = @_; $test_nb++; if( $expected ne $got) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; if( length( $expected) > 20) { warn "$message:\ngot : '$got'\n"; } else { warn "$message: got '$got'\n"; } croak if $TFATAL; return 0; } } sub matches { my $got = shift; my $expected_regexp= shift; my $message = shift; $test_nb++; if( $got=~ /$expected_regexp/) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; warn "$message: expected to match /$expected_regexp/, got '$got'\n"; croak if $TFATAL; return 0; } } sub not_matches { my $got = shift; my $expected_regexp= shift; my $message = shift; $test_nb++; if( $got!~ /$expected_regexp/) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; warn "$message: expected to NOT match /$expected_regexp/, got '$got'\n"; croak if $TFATAL; return 0; } } sub ok { my $cond = shift; my $message=shift; $test_nb++; if( $cond) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; warn "$message: false\n"; croak if $TFATAL; return 0; } } sub nok { my $cond = shift; my $message=shift; $test_nb++; if( !$cond) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; warn "$message: true (should be false): '$cond'\n"; croak if $TFATAL; return 0; } } sub is_undef { my $cond = shift; my $message=shift; $test_nb++; if( ! defined( $cond)) { print "ok $test_nb"; print "$message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; warn "$message is defined: '$cond'\n"; croak if $TFATAL; return 0; } } my $devnull = File::Spec->devnull; sub sys_ok { my $message=pop; $test_nb++; my $status= system join " ", @_, "2>$devnull"; if( !$status) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; } else { print "not ok $test_nb\n"; warn "$message: $!\n"; } } sub sys_nok { my $message=pop; $test_nb++; my $status= system join " ", @_, "2>$devnull"; if( $status) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; } else { print "not ok $test_nb\n"; warn "$message: $!\n"; } } sub is_like { my( $got, $expected, $message) = @_; $message ||=''; $test_nb++; if( clean_sp( $expected) eq clean_sp( $got)) { print "ok $test_nb"; print " $message" if( $TDEBUG); print "\n"; return 1; } else { print "not ok $test_nb\n"; if( length( $expected) > 20) { warn "$message:\nexpected: '$expected'\ngot : '$got'\n"; } else { warn "$message: expected '$expected', got '$got'\n"; } warn "compact expected: ", clean_sp( $expected), "\n", "compact got: ", clean_sp( $got), "\n"; croak if $TFATAL; return 0; } } sub etest { my ($elt, $gi, $id, $message)= @_; $test_nb++; unless( $elt) { print "not ok $test_nb\n -- $message\n"; warn " -- no element returned"; return; } if( ($elt->tag eq $gi) && ($elt->att( 'id') eq $id)) { print "ok $test_nb\n"; return $elt; } print "not ok $test_nb\n -- $message\n"; warn " -- expecting ", $gi, " ", $id, "\n"; warn " -- found ", $elt->tag, " ", $elt->id, "\n"; return $elt; } # element text test sub ttest { my ($elt, $text, $message)= @_; $test_nb++; unless( $elt) { print "not ok $test_nb\n -- $message\n"; warn " -- no element returned "; return; } if( $elt->text eq $text) { print "ok $test_nb\n"; return $elt; } print "not ok $test_nb\n -- $message\n"; warn " expecting ", $text, "\n"; warn " found ", $elt->text, "\n"; return $elt; } # testing if the result is a strings sub stest { my ($result, $expected, $message)= @_; $result ||=''; $expected ||=''; $test_nb++; if( $result eq $expected) { print "ok $test_nb\n"; } else { print "not ok $test_nb\n -- $message\n"; warn " expecting ", $expected, "\n"; warn" found ", $result, "\n"; } } # element sprint test sub sttest { my ($elt, $text, $message)= @_; $test_nb++; unless( $elt) { print "not ok $test_nb\n -- $message\n"; warn " -- no element returned "; return; } if( $elt->sprint eq $text) { print "ok $test_nb\n"; return $elt; } print "not ok $test_nb\n -- $message\n"; warn " expecting ", $text, "\n"; warn " found ", $elt->sprint, "\n"; return $elt; } # testing if the result matches a pattern sub mtest { my ($result, $expected, $message)= @_; $test_nb++; if( $result=~ /$expected/) { print "ok $test_nb\n"; } else { print "not ok $test_nb\n -- $message\n"; warn " expecting ", $expected, "\n"; warn" found ", $result, "\n"; } } # test 2 files sub ftest { my ($result_file, $expected_file, $message)= @_; my $result_string= clean_sp( slurp( $result_file)); my $expected_string= clean_sp( slurp( $expected_file)); $test_nb++; if( $result_string eq $expected_string) { print "ok $test_nb\n"; } else { print "not ok $test_nb\n -- $message\n"; warn " expecting ", $expected_string, "\n"; warn " found ", $result_string, "\n"; } } sub slurp { my( $file)= @_; local undef $/; open( FH, "<$file") or die "cannot slurp '$file': $!\n"; my $content=; close FH; return $content; } sub spit { my( $file, $content)= @_; open( FH, ">$file") or die "cannot spit '$file': $!\n"; print FH $content; close FH; } sub stringifyh { my %h= @_; return '' unless @_; return join ':', map { "$_:$h{$_}"} sort keys %h; } sub stringify { return '' unless @_; return join ":", @_; } my %seen_message; sub skip { my( $nb_skip, $message)= @_; $message ||=''; unless( $seen_message{$message}) { warn "\n$message: skipping $nb_skip tests\n"; $seen_message{$message}++; } for my $test ( ($test_nb + 1) .. ($test_nb + $nb_skip)) { print "ok $test\n"; warn "skipping $test ($message)\n" if( $TDEBUG); } $test_nb= $test_nb + $nb_skip; return 1; } } sub tags { return join ':', map { $_->gi } @_ } sub ids { return join ':', map { $_->att( 'id') || '<' . $_->gi . ':no_id>' } @_ } sub id_list { my $list= join( "-", sort keys %{$_[0]->{twig_id_list}}); if( !defined $list) { $list= ''; } return $list; } sub id { my $elt= $_[0]->elt_id( $_[1]) or return "unknown"; return $elt->att( $_[0]->{twig_id}); } sub clean_sp { my $str= shift; $str=~ s{\s+}{}g; return $str; } sub normalize_xml { my $xml= shift; $xml=~ s{\n}{}g; $xml=~ s{'}{"}g; #' $xml=~ s{ />}{/>}g; return $xml; } sub xml_escape { my $string= shift; #$string=~ s{&}{&}g; $string=~ s{<}{<}g; $string=~ s{>}{>}g; $string=~ s{"}{"}g; #" $string=~ s{'}{'}g; #' return $string; } sub hash_ent_text { my %ents= @_; return map { $_ => "" } keys %ents; } sub string_ent_text { my %ents= @_; my %hash_ent_text= hash_ent_text( %ents); return join( '', map { $hash_ent_text{$_} } sort keys %hash_ent_text); } 1; sub _use { my( $module, $version)= @_; $version ||= 0; $version=~ s{^\s*(\d+\.\d+).*}{$1}; # trim version numbers like 2.42_01 if( eval "require $module") { import $module; no strict 'refs'; my $mversion= ${"${module}::VERSION"}; $mversion=~ s{^\s*(\d+\.\d+).*}{$1}; # trim version numbers like 2.42_01 if( $mversion >= $version ) { return 1; } else { croak if $TFATAL; return 0; } } } sub test_get_xpath { my( $t, $exp, $expected)= @_; is( ids( $t->get_xpath( $exp)), $expected, "$exp xpath exp"); } sub perl_io_layer_used { if( $] >= 5.008) { return eval '${^UNICODE} & 24'; } # in a eval to pass tests in 5.005 else { croak if $TFATAL; return 0; } } # slurp and discard locale errors sub slurp_error { my( $file)= @_; my $error= eval { slurp( $file); } || ''; $error=~ s{^\s$}{}mg; $error=~ s{^[^:]+: warning:.*$}{}mg; return $error; } sub used_perl { my $perl; if( $^O eq 'VMS') { $perl= $Config{perlpath}; } # apparently $^X does not work on VMS else { $perl= $^X; } # but $Config{perlpath} does not work in 5.005 if ($^O ne 'VMS' && $Config{_exe} && $perl !~ m{$Config{_exe}$}i) { $perl .= $Config{_exe}; } $perl .= " -Iblib/lib"; if( $ENV{TEST_COVER}) { $perl .= " -MDevel::Cover"; } return $perl; } # scrubs xhtml generated by tools from likely to change bits sub scrub_xhtml { my( $html)= @_; $html=~ s{]*>}{}; # scrub doctype $html=~ s{\s*xmlns="[^"]*"}{}; # scrup namespace declaration return $html; } __END__ =head1 SYNOPSYS use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use tools; XML-Twig-3.50/t/test2_3.res0000644000175000017500000000162112637027414015522 0ustar mrodrigumrodrigu ]>
S1 I1S1 I2S1 TitleS1 P1S2 P2Note P1S1 para 3
S2 introS2 TitleS2 P1S2 P2S2 P3
Annex TitleAnnex P1Annex P2
XML-Twig-3.50/t/test_xml_split.t0000755000175000017500000001360412346001775016771 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use Config; my $devnull = File::Spec->devnull; my $DEBUG=0; my $extra_flags= $Devel::Cover::VERSION ? '-MDevel::Cover -Ilib' : '-Ilib'; # be cautious: run this only on systems I have tested it on my %os_ok=( linux => 1, solaris => 1, darwin => 1, MSWin32 => 1); if( !$os_ok{$^O}) { print "1..1\nok 1\n"; warn "skipping, test runs only on some OSs\n"; exit; } if( $] < 5.006) { print "1..1\nok 1\n"; warn "skipping, xml_merge runs only on perl 5.6 and later\n"; exit; } print "1..59\n"; my $perl= $Config{perlpath}; if ($^O ne 'VMS') { $perl .= $Config{_exe} unless $perl =~ m/$Config{_exe}$/i; } $perl.= " $extra_flags"; my $xml_split = File::Spec->catfile( "tools", "xml_split", "xml_split"); my $xml_merge = File::Spec->catfile( "tools", "xml_merge", "xml_merge"); my $xml_pp = File::Spec->catfile( "tools", "xml_pp", "xml_pp"); sys_ok( "$perl -c $xml_split", "xml_split compilation"); sys_ok( "$perl -c $xml_merge", "xml_merge compilation"); my $test_dir = File::Spec->catfile( "t", "test_xml_split"); my $test_file = File::Spec->catfile( "t", "test_xml_split.xml"); my $base_nb; # global, managed by test_split_merge test_split_merge( $test_file, "", "" ); test_split_merge( $test_file, "-i", "-i" ); test_split_merge( $test_file, "-c elt1", "" ); test_split_merge( $test_file, "-i -c elt1", "-i" ); test_split_merge( $test_file, "-c elt2", "" ); test_split_merge( $test_file, "-i -c elt2", "-i" ); test_split_merge( $test_file, "-s 1K", "" ); test_split_merge( $test_file, "-i -s 1K", "-i" ); test_split_merge( $test_file, "-l 1", "" ); test_split_merge( $test_file, "-i -l 1", "-i" ); test_split_merge( $test_file, "-g 5", "" ); test_split_merge( $test_file, "-i -g 5", "-i" ); $test_file=File::Spec->catfile( "t", "test_xml_split_entities.xml"); test_split_merge( $test_file, "", "" ); test_split_merge( $test_file, "-g 2", "" ); test_split_merge( $test_file, "-l 1", "" ); $test_file=File::Spec->catfile( "t", "test_xml_split_w_decl.xml"); test_split_merge( $test_file, "", "" ); test_split_merge( $test_file, "-c elt1", "" ); test_split_merge( $test_file, "-g 2", "" ); test_split_merge( $test_file, "-l 1", "" ); test_split_merge( $test_file, "-s 1K", "" ); test_split_merge( $test_file, "-g 2 -l 2", "" ); if( _use( 'IO::CaptureOutput')) { test_error( $xml_split => "-h", 'xml_split '); test_error( $xml_merge => "-h", 'xml_merge '); test_out( $xml_split => "-V", 'xml_split '); test_out( $xml_merge => "-V", 'xml_merge '); if( `pod2text -h` && $^O !~ m{^MS}) { test_out( $xml_split => "-m", 'NAME\s*xml_split '); test_out( $xml_merge => "-m", 'NAME\s*xml_merge '); test_out( $xml_pp => "-h", 'NAME\s*xml_pp '); } else { skip( 3, "pod2text not found in the path, cannot use -m oprion for xml_split and xml_merge"); } test_error( $xml_split => "-c foo -s 1K", 'cannot use -c and -s at the same time'); test_error( $xml_split => "-g 100 -s 1K", 'cannot use -g and -s at the same time'); test_error( $xml_split => "-g 100 -c fo", 'cannot use -g and -c at the same time'); test_error( $xml_split => "-s 1Kc", 'invalid size'); test_error( $xml_pp => "-s --style", 'usage:'); test_error( $xml_pp => "-i --in_place", 'usage:'); test_error( $xml_pp => "-e utf8 --encoding utf8", 'usage:'); test_error( $xml_pp => "-l --load", 'usage:'); } else { skip( 15, 'need IO::CaptureOutput to test tool options'); } sub test_error { my( $command, $options, $expected)= @_; my( $stdout, $stderr, $success, $exit_code) = IO::CaptureOutput::capture_exec( "$perl $command $options test_xml_split.xml"); matches( $stderr, qr/$expected/, "$command $options"); } sub test_out { my( $command, $options, $expected)= @_; my( $stdout, $stderr, $success, $exit_code) = IO::CaptureOutput::capture_exec( "$perl $command $options test_xml_split.xml"); matches( $stdout, qr/^$expected/, "$command $options"); } sub test_split_merge { my( $file, $split_opts, $merge_opts)= @_; $split_opts ||= ''; $merge_opts ||= ''; $base_nb++; my $verbifdebug = $DEBUG ? '-v' : ''; my $expected_base= File::Spec->catfile( "$test_dir", "test_xml_split_expected-$base_nb"); my $base= File::Spec->catfile( "$test_dir", "test_xml_split-$base_nb"); systemq( "$perl $xml_split $verbifdebug -b $base $split_opts $file"); ok( same_files( $expected_base, $base), "xml_split $split_opts $test_file"); my $merged= "$base.xml"; system "$perl $xml_merge $verbifdebug -o $merged $merge_opts $base-00.xml"; system "$perl $xml_pp -i $merged"; ok( same_file( $merged, $file), "xml_merge $merge_opts $test_file ($merged $base-00.xml"); unlink( glob( "$base*")) unless( $DEBUG); } sub same_files { my( $expected_base, $base)= @_; my $nb="00"; while( -f "$base-$nb.xml") { my( $real, $expected)= ( "$base-$nb.xml", "$expected_base-$nb.xml"); if( ! -z $expected) { _use( 'File::Copy'); copy( $real, $expected); } unless( same_file( $expected, $real)) { warn " $expected and $real are different"; if( $DEBUG) { warn `diff $expected, $real`; } return 0; } $nb++; } return 1; } sub same_file { my( $file1, $file2)= @_; my $eq= slurp_mod( $file1) eq slurp_mod( $file2); if( $DEBUG && ! $eq) { system "diff $file1 $file2\n"; } return $eq; } # slurp and remove spaces and _expected from the file sub slurp_mod { my( $file)= @_; local undef $/; open( FHSLURP, "<$file") or return "$file not found:$!"; my $content=; $content=~ s{\s}{}g; $content=~ s{_expected}{}g; return $content; } sub systemq { if( !$DEBUG) { system "$_[0] 1>$devnull 2>$devnull"; } else { warn "$_[0]\n"; system $_[0]; } } XML-Twig-3.50/t/tests_3_23.t0000755000175000017500000000204712346001774015605 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; use XML::Twig; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; my $DEBUG=0; print "1..6\n"; if( _use( 'XML::XPathEngine') || _use( 'XML::XPath') ) { _use( 'XML::Twig::XPath'); my $t= XML::Twig::XPath->nparse( q{ foobar bazfoobar }); is( $t->findvalue( '//e[.="foo"]/@a'), "ea1", 'xpath on attributes'); is( $t->findvalue( '//s[./e="foo"]/@a'), "sa1", 'xpath with elt content test'); is( $t->findvalue( '/d/s[e="foo"]/@a'), "sa1", 'xpath with elt content test (short form)'); } else { skip( 3); } { my $t= XML::Twig->nparse( ''); my @xpath_result= $t->get_xpath( '/'); is( ref( $xpath_result[0]), 'XML::Twig', "get_xpath( '/')"); @xpath_result= $t->get_xpath( '/doc[1]'); is( $xpath_result[0]->tag, 'doc', "get_xpath( '/doc[1]')"); @xpath_result= $t->get_xpath( '/notdoc[1]'); is( scalar( @xpath_result), 0, "get_xpath( '/notdoc[1]')"); } XML-Twig-3.50/t/test_xml_split_g.t0000755000175000017500000000466512346001775017306 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use Config; my $devnull = File::Spec->devnull; my $DEBUG=1; # be cautious: run this only on systems I have tested it on my %os_ok=( linux => 1, solaris => 1, darwin => 1, MSWin32 => 1); if( !$os_ok{$^O}) { print "1..1\nok 1\n"; warn "skipping, test runs only on some OSs\n"; exit; } if( $] < 5.006) { print "1..1\nok 1\n"; warn "skipping, xml_merge runs only on perl 5.6 and later\n"; exit; } print "1..13\n"; my $perl = used_perl(); my $xml_split = File::Spec->catfile( "tools", "xml_split", "xml_split"); my $xml_merge = File::Spec->catfile( "tools", "xml_merge", "xml_merge"); sys_ok( "$perl -c $xml_split", "xml_split compilation"); sys_ok( "$perl -c $xml_merge", "xml_merge compilation"); my $xml= q{} . join( "\n ", map { elt( $_) } (1..10)) . qq{\n}; my $xml_file= "test_xml_split_g.xml"; spit( $xml_file => $xml); systemq( "$perl $xml_split -g 3 -n 3 $xml_file"); my $main_file= "test_xml_split_g-000.xml"; my @files= map { sprintf( "test_xml_split_g-%03d.xml", $_) } (1..4); foreach ( $main_file, @files) { ok( -f $_, "created $_"); } is_like( slurp( "test_xml_split_g-000.xml"), q{} . join( '', map { ""} @files) . q{}, "main file content"); is_like( slurp( "test_xml_split_g-001.xml"), sub_file( 1..3), "test_xml_split_g-001.xml content"); is_like( slurp( "test_xml_split_g-002.xml"), sub_file( 4..6), "test_xml_split_g-002.xml content"); is_like( slurp( "test_xml_split_g-003.xml"), sub_file( 7..9), "test_xml_split_g-003.xml content"); is_like( slurp( "test_xml_split_g-004.xml"), sub_file( 10), "test_xml_split_g-004.xml content"); unlink $xml_file; systemq( "$perl $xml_merge $main_file > $xml_file"); is_like( slurp( $xml_file), $xml, "merge result"); unlink $xml_file, $main_file, @files; sub sub_file { my @elt_nb= @_; return q{} . join( '', map { elt( $_)} @elt_nb) . q{}; } sub elt { my( $nb)= @_; return qq{element $nb}; } # slurp and remove spaces from the file sub slurp_trimmed { my( $file)= @_; local undef $/; open( FHSLURP, "<$file") or return "$file not found:$!"; my $content=; $content=~ s{\s}{}g; return $content; } sub systemq { warn "$_[0]\n" if( !$DEBUG); system $_[0]; } XML-Twig-3.50/t/dummy.dtd0000644000175000017500000000042512346001774015353 0ustar mrodrigumrodrigu XML-Twig-3.50/t/test_errors.t0000755000175000017500000003725412414166625016303 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # test error conditions use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use Config; use tools; #$|=1; use XML::Twig; my $TMAX=121; print "1..$TMAX\n"; my $error_file= File::Spec->catfile('t','test_errors.errors'); my( $q, $q2) = ( ($^O eq "MSWin32") || ($^O eq 'VMS') ) ? ('"', "'") : ("'", '"'); { # test insufficient version of XML::Parser (not that easy, it is already too late here) my $need_version= 2.23; use Config; my $perl= used_perl(); my $version= $need_version - 0.01; unlink $error_file if -f $error_file; if ($^O eq 'VMS') { system( qq{$perl $q-Mblib$q -e$q use vmsish qw(hushed);use XML::Parser; BEGIN { \$XML::Parser::VERSION=$version}; use XML::Twig $q 2> $error_file}); } else { system( qq{$perl $q-Iblib/lib$q -e$q use XML::Parser; BEGIN { \$XML::Parser::VERSION=$version}; use XML::Twig $q 2> $error_file}); } ok( -f $error_file, "error generated for low version of XML::Parser"); matches( slurp_error( $error_file), "need at least XML::Parser version ", "error message for low version of XML::Parser"); $version= $need_version; unlink $error_file if -f $error_file; system( qq{$perl $q-Mblib$q -e$q use XML::Parser; BEGIN { \$XML::Parser::VERSION=$version}; use XML::Twig $q 2> $error_file}); ok( ! -f $error_file || slurp_error( $error_file)!~ "need at least XML::Parser version", "no error generated for proper version of XML::Parser" ); $version= $need_version + 0.01; unlink $error_file if -f $error_file; system( qq{$^X -e$q use XML::Parser; BEGIN { \$XML::Parser::VERSION=$version}; use XML::Twig$q 2> $error_file}); ok( ! -f $error_file || slurp_error( $error_file)!~ "need at least XML::Parser version", "no error generated for high version of XML::Parser" ); unlink $error_file if -f $error_file; } my $warning; my $init_warn= $SIG{__WARN__}; { $SIG{__WARN__}= sub { $warning= join '', @_; }; XML::Twig->new( dummy => 1); $SIG{__WARN__}= $init_warn; matches( $warning, "invalid option Dummy", "invalid option"); } { eval { XML::Twig::_slurp( $error_file) }; matches( $@, "cannot open '\Q$error_file\E'", "_slurp inexisting file"); } { eval {XML::Twig->new->parse( '')->root->first_child( 'du,')}; matches( $@, "wrong navigation condition", "invalid navigation expression"); } { eval {XML::Twig->new->parse( '')->root->first_child( '@val=~/[/')}; matches( $@, "wrong navigation condition", "invalid navigation expression"); } { eval {XML::Twig->new( twig_print_outside_roots => 1)}; matches( $@, "cannot use twig_print_outside_roots without twig_roots", "invalid option"); } { eval {XML::Twig->new( keep_spaces => 1, discard_spaces => 1 )}; matches( $@, "cannot use both keep_spaces and discard_spaces", "invalid option combination keep_spaces and discard_spaces"); eval {XML::Twig->new( keep_spaces => 1, discard_all_spaces => 1 )}; matches( $@, "cannot use both keep_spaces and discard_all_spaces", "invalid option combination keep_spaces and discard_all_spaces"); eval {XML::Twig->new( keep_spaces => 1, keep_spaces_in => ['p'])}; matches( $@, "cannot use both keep_spaces and keep_spaces_in", "invalid option combination keep_spaces and keep_spaces_in"); eval {XML::Twig->new( discard_spaces => 1, discard_all_spaces => 1)}; matches( $@, "cannot use both discard_spaces and discard_all_spaces", "invalid option combination discard_spaces and discard_all_spaces"); eval {XML::Twig->new( discard_spaces => 1, keep_spaces_in => ['p'])}; matches( $@, "cannot use both discard_spaces and keep_spaces_in", "invalid option combination discard_spaces and keep_spaces_in"); eval {XML::Twig->new( keep_spaces_in => [ 'doc' ], discard_spaces_in => ['p'])}; matches( $@, "cannot use both keep_spaces_in and discard_spaces_in", "invalid option combination keep_spaces_in and discard_spaces_in"); eval {XML::Twig->new( discard_spaces => 1, discard_spaces_in => ['p'])}; matches( $@, "cannot use both discard_spaces and discard_spaces_in", "invalid option combination discard_spaces and discard_spaces_in"); eval {XML::Twig->new( keep_spaces_in => [ 'doc' ], discard_all_spaces => 1)}; matches( $@, "cannot use both keep_spaces_in and discard_all_spaces", "invalid option combination keep_spaces_in and discard_all_spaces"); eval {XML::Twig->new( discard_all_spaces => 1, discard_spaces_in => ['p'])}; matches( $@, "cannot use both discard_all_spaces and discard_spaces_in", "invalid option combination discard_all_spaces and discard_spaces_in"); eval {XML::Twig->new( comments => 'wrong') }; matches( $@, "wrong value for comments argument: 'wrong'", "invalid option value for comment"); eval {XML::Twig->new( pi => 'wrong') }; matches( $@, "wrong value for pi argument: 'wrong'", "invalid option value for pi"); } { my $t=XML::Twig->new->parse( '

p1

p 2

'); my $elt= $t->root; eval { $elt->sort_children( sub { }, type => 'wrong'); }; matches( $@, "wrong sort type 'wrong', should be either 'alpha' or 'numeric'", "sort type"); } { foreach my $wrong_path ( 'wrong path', 'wrong##path', '1', '1tag', '///tag', 'tag/') { eval {XML::Twig->new( twig_handlers => { $wrong_path => sub {}});}; matches( $@, "unrecognized expression in handler: '$wrong_path'", "wrong handler ($wrong_path)"); } eval {XML::Twig->new( input_filter => 'dummy')}; matches( $@, "invalid input filter:", "input filter"); eval {XML::Twig->new( input_filter => {})}; matches( $@, "invalid input filter:", "input filter"); } { foreach my $bad_tag ( 'toto', '<1toto', 'new( twig_handlers => { sax => sub { $_[0]->toSAX1 } }); eval {$t->parse( '')}; matches( $@, "cannot use toSAX1 while parsing", "toSAX1 during parsing"); } { my $t= XML::Twig->new( twig_handlers => { sax => sub { $_[0]->toSAX2 } }); eval {$t->parse( '')}; matches( $@, "cannot use toSAX2 while parsing", "toSAX2 during parsing"); } { my $t= XML::Twig->new->parse( ''); foreach my $bad_cond ( 'foo bar', 'foo:bar:baz', '.', '..', '...', '**', 'con[@to:ta:ti]') { eval { $t->root->first_child( qq{$bad_cond})}; matches( $@, "wrong navigation condition '\Q$bad_cond\E'", "bad navigation condition '$bad_cond'"); } } { my $t= XML::Twig->new->parse( ''); eval { XML::Twig->parse( twig_handlers => { q{foo[@a="$sd"]} => sub { } }, ""); }; matches( $@, "^wrong handler condition", 'perl syntax in attribute value'); } { my $t= XML::Twig->new->parse( ''); eval { $t->root->set_field( '*[2]'); }; matches( $@, "can't create a field name from", 'set_field'); } { my $t= XML::Twig->new( twig_handlers => { erase => sub { $_->parent->erase } }); eval { $t->parse( '

toto

'); }; matches( $@, "trying to erase an element before it has been completely parsed", 'erase current element'); } { my $t= XML::Twig->new->parse( ''); my $e= $t->first_elt( 'erase')->cut; eval { $e->erase }; matches( $@, "can only erase an element with no parent if it has a single child", 'erase cut element'); $e->paste( $t->root); eval { $e->paste( first_child => $t->root); }; matches( $@, "cannot paste an element that belongs to a tree", 'paste uncut element'); $e->cut; eval { $e->paste( $t->root => 'first_child' ); }; matches( $@, "wrong argument order in paste, should be", 'paste uncut element'); eval { $e->paste( first_child => {} ); }; matches( $@, "wrong target type in paste: 'HASH', should be XML::Twig::Elt", 'paste with wrong ref'); eval { $e->paste( 'first_child' ); }; matches( $@, "missing target in paste", 'paste with no target'); eval { $e->paste( 'first_child', 1 ); }; matches( $@, 'wrong target type in paste \(not a reference\)', 'paste with no ref'); eval { $e->paste( 'first_child', bless( {}, 'foo') ); }; matches( $@, "wrong target type in paste: 'foo'", 'paste with wrong object type'); eval { $e->paste( wrong => $t->root ); }; matches( $@, "tried to paste in wrong position 'wrong'", 'paste in wrong position'); eval { $e->paste( before => $t->root); }; matches( $@, "cannot paste before root", 'paste before root'); eval { $e->paste( after => $t->root); }; matches( $@, "cannot paste after root", 'paste after root'); eval { $e->paste_before( $t->root); }; matches( $@, "cannot paste before root", 'paste before root'); eval { $e->paste_after( $t->root); }; matches( $@, "cannot paste after root", 'paste after root'); } { my $t= XML::Twig->new->parse( '

text1

text2

'); my $p1= $t->root->first_child( 'p'); my $p2= $t->root->first_child( 'p[2]'); eval { $p1->merge_text( 'toto'); } ; matches( $@, "invalid merge: can only merge 2 elements", 'merge elt and string'); eval { $p1->merge_text( $p2); } ; matches( $@, "invalid merge: can only merge 2 text elements", 'merge non text elts'); $p1->first_child->merge_text( $p2->first_child); is( $t->sprint, '

text1text2

', 'merge_text'); my $p3= XML::Twig::Elt->new( '#CDATA' => 'foo'); eval { $p1->first_child->merge_text( $p3); }; matches( $@, "invalid merge: can only merge 2 text elements", 'merge cdata and pcdata elts'); } { my $t= XML::Twig->new; $t->save_global_state; eval { $t->set_pretty_print( 'foo'); }; matches( $@, "invalid pretty print style 'foo'", 'invalid pretty_print style'); eval { $t->set_pretty_print( 987); }; matches( $@, "invalid pretty print style 987", 'invalid pretty_print style'); eval { $t->set_empty_tag_style( 'foo'); }; matches( $@, "invalid empty tag style 'foo'", 'invalid empty_tag style'); eval { $t->set_empty_tag_style( '987'); }; matches( $@, "invalid empty tag style 987", 'invalid empty_tag style'); eval { $t->set_quote( 'foo'); }; matches( $@, "invalid quote 'foo'", 'invalid quote style'); eval { $t->set_output_filter( 'foo'); }; matches( $@, "invalid output filter 'foo'", 'invalid output filter style'); eval { $t->set_output_text_filter( 'foo'); }; matches( $@, "invalid output text filter 'foo'", 'invalid output text filter style'); } { my $t= XML::Twig->new->parse( ''); my @methods= qw( depth in_element within_element context current_line current_column current_byte recognized_string original_string xpcroak xpcarp xml_escape base current_element element_index position_in_context ); my $method; foreach $method ( @methods) { eval "\$t->$method"; matches( $@, "calling $method after parsing is finished", $method); } $SIG{__WARN__}= $init_warn; } { my $t= XML::Twig->new->parse( ''); my $elt= $t->root->first_child( 'elt')->cut; foreach my $pos ( qw( before after)) { eval { $elt->paste( $pos => $t->root); }; matches( $@, "cannot paste $pos root", "paste( $pos => root)"); } } { my $t= XML::Twig->new->parse( 'f1f2'); eval { $t->root->simplify( group_tags => { a => 'f1' }); }; matches( $@, "error in grouped tag a", "grouped tag error f1"); eval { $t->root->simplify( group_tags => { a => 'f2' }); }; matches( $@, "error in grouped tag a", "grouped tag error f2"); eval { $t->root->simplify( group_tags => { a => 'f3' }); }; matches( $@, "error in grouped tag a", "grouped tag error f3"); } { eval { XML::Twig::Elt->parse( 'foo')->subs_text( "foo", '&elt( 0/0)'); }; matches( $@, "(invalid replacement expression |Illegal division by zero)", "invalid replacement expression in subs_text"); } { eval { my $t=XML::Twig->new( twig_handlers => { e => sub { $_[0]->parse( "") } }); $t->parse( ""); }; matches( $@, "cannot reuse a twig that is already parsing", "error re-using a twig during parsing"); } { ok( XML::Twig->new( twig_handlers => { 'elt[string()="foo"]' => sub {}} ), 'twig_handlers with string condition' ); eval { XML::Twig->new( twig_roots => { 'elt[string()="foo"]' => sub {}} ) }; matches( $@, "string.. condition not supported on twig_roots option", 'twig_roots with string condition' ); ok( XML::Twig->new( twig_handlers => { 'elt[string()=~ /foo/]' => sub {}} ), 'twig_handlers with regexp' ); eval { XML::Twig->new( twig_roots => { 'elt[string()=~ /foo/]' => sub {}} ) }; matches( $@, "string.. condition not supported on twig_roots option", 'twig_roots with regexp condition' ); #ok( XML::Twig->new( twig_handlers => { 'elt[string()!="foo"]' => sub {}} ), 'twig_handlers with !string condition' ); #eval { XML::Twig->new( twig_roots => { 'elt[string()!="foo"]' => sub {}} ) }; #matches( $@, "string.. condition not supported on twig_roots option", 'twig_roots with !string condition' ); #ok( XML::Twig->new( twig_handlers => { 'elt[string()!~ /foo/]' => sub {}} ), 'twig_handlers with !regexp' ); #eval { XML::Twig->new( twig_roots => { 'elt[string()!~ /foo/]' => sub {}} ) }; #matches( $@, "regexp condition not supported on twig_roots option", 'twig_roots with !regexp condition' ); } { XML::Twig::_disallow_use( "XML::Parser"); nok( XML::Twig::_use( "XML::Parser"), '_use XML::Parser (disallowed)'); XML::Twig::_allow_use( "XML::Parser"); ok( XML::Twig::_use( "XML::Parser"), '_use XML::Parser (allowed)'); ok( XML::Twig::_use( "XML::Parser"), '_use XML::Parser (allowed, 2cd try)'); nok( XML::Twig::_use( "XML::Parser::foo::nonexistent"), '_use XML::Parser::foo::nonexistent'); } { XML::Twig::_disallow_use( "Tie::IxHash"); eval { XML::Twig->new( keep_atts_order => 1); }; matches( $@, "Tie::IxHash not available, option keep_atts_order not allowed", 'no Tie::IxHash' ); } { eval { XML::Twig::_first_n { $_ } 0, 1, 2, 3; }; matches( $@, "illegal position number 0", 'null argument to _first_n' ); } { if( ( $] <= 5.008) || ($^O eq 'VMS') ) { skip(1, 'test perl -CSDAL'); } elsif( ! can_check_for_pipes() ) { skip( 1, 'your perl cannot check for pipes'); } else { my $infile= File::Spec->catfile('t','test_new_features_3_22.xml'); my $script= File::Spec->catfile('t','test_error_with_unicode_layer'); my $error=File::Spec->catfile('t','error.log'); my $perl = used_perl(); my $cmd= qq{$perl $q-CSDAL$q $script $infile 2>$error}; system $cmd; matches( slurp( $error), "cannot parse the output of a pipe", 'parse a pipe with perlIO layer set to UTF8 (RT #17500)'); } } { my $e1= XML::Twig::Elt->new( 'foo'); my $e2= XML::Twig::Elt->new( 'foo'); eval { $e1->paste_before( $e2); }; matches( $@, "cannot paste before an orphan element", 'paste before an orphan element' ); eval { $e1->paste_after( $e2); }; matches( $@, "cannot paste after an orphan element", 'paste after an orphan element' ); } { my $r= XML::Twig->parse( '')->root; eval { $r->find_nodes( '//foo/1following::') }; matches( $@, "error in xpath expression", 'error in xpath expression //foo/following::'); } # tests for https://rt.cpan.org/Public/Bug/Display.html?id=97461 (wrong error message due to filehandle seen as a file) { eval { XML::Twig->new->parse( do { open( my $fh, '<', $0); $fh}); }; not_matches( $@, "you seem to have used the parse method on a filename", "parse on a filehandle containing invalid XML"); open FOO, "<$0"; eval { XML::Twig->new->parse( \*FOO); }; not_matches( $@, "you seem to have used the parse method on a filename", "parse on a GLOBAL filehandle containing invalid XML"); } exit 0; sub can_check_for_pipes { my $perl = used_perl(); open( FH, qq{$perl -e$q print 1$q |}) or die "error opening pipe: $!"; return -p FH; } XML-Twig-3.50/t/latin1_accented_char.iso-8859-10000644000175000017500000000000212346001775021013 0ustar mrodrigumrodrigué XML-Twig-3.50/t/xmlxpath_18axispreceding.t0000755000175000017500000000127612346001775020644 0ustar mrodrigumrodrigu#!/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/preceding::*'); ok(@nodes, 4); @nodes = $t->findnodes( '//GGG/preceding::*'); ok(@nodes, 8); exit 0; __DATA__ XML-Twig-3.50/t/test_3_30.t0000755000175000017500000003407212346001774015423 0ustar mrodrigumrodrigu#!/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=87; print "1..$TMAX\n"; if( _use( 'Tie::IxHash')) { # test the new indent format example from http://tinyurl.com/2kwscq my $doc=q{ }; my $formatted= XML::Twig->parse( keep_atts_order => 1, pretty_print => cvs => $doc)->sprint; is( $formatted, $doc, 'cvs pretty_print'); } else { skip( 1, "Tie::IxHash not available, cannot test the cvs pretty_print option"); } if( $XML::Parser::VERSION > 2.27) { my $test_dir= "ent_test"; mkdir( $test_dir, 0777) or die "cannot create $test_dir: $!" unless( -d $test_dir); my $xml_file_base = "test.xml"; my $xml_file= File::Spec->catfile( $test_dir => $xml_file_base); my $ent_file_base = "ent.xml"; my $ent_file= File::Spec->catfile( $test_dir => $ent_file_base); my $doc= qq{ ]>&ent;}; my $ent= qq{}; spit( $xml_file, $doc); spit( $ent_file, $ent); my $expected= ''; is( XML::Twig->parse( pretty_print => 'none', $xml_file)->root->sprint, $expected, 'entity resolving when file is in a subdir'); unlink $xml_file or die "cannot remove $xml_file: $!"; unlink $ent_file or die "cannot remove $ent_file: $!"; rmdir $test_dir or die "cannot remove $test_dir: $!"; } else { skip( 1 => "known bug with old XML::Parser versions: base uri not taken into account,\n" . "see RT #25113 at http://rt.cpan.org/Public/Bug/Display.html?id=25113" ); } { my $doc= ""; my $doc_file= "doc.xml"; spit( $doc_file, $doc); my $t= XML::Twig->new; foreach (1..3) { $t->parse( $doc); is( $t->sprint, $doc, "re-using a twig with parse (run $_)"); $t->parse( $doc); is( $t->sprint, $doc, "re-using a twig with parse (run $_)"); $t->parsefile( $doc_file); is( $t->sprint, $doc, "re-using a twig with parsefile (run $_)"); $t->parsefile( $doc_file); is( $t->sprint, $doc, "re-using a twig with parsefile (run $_)"); } unlink $doc_file; } { my $invalid_doc= "
"; my $invalid_doc_file= "invalid_doc.xml"; spit( $invalid_doc_file, $invalid_doc); my $expected="e"; my( $result); my $expected_sprint=""; my $t= XML::Twig->new( twig_handlers => { e => sub { $result.= $_->tag; shift->finish_now } }); foreach (1..3) { $result=''; $t->parse( $invalid_doc); is( $result, $expected, "finish_now with parse (run $_)"); is( $t->sprint, $expected_sprint, "finish_now with parse (sprint, run $_)"); $result=''; $t->parsefile( $invalid_doc_file); is( $result, $expected, "finish_now with parsefile (run $_)"); is( $t->sprint, $expected_sprint, "finish_now with parse (sprint, run $_)"); } unlink $invalid_doc_file; } { my $doc1=qq{\n\n]>\n t1 &e1; &e2;}; my $doc2=qq{\n\n]>\n t1 &e1; &e3;}; (my $edoc1 = $doc1)=~ s{&e(\d);}{[e$1]}g; (my $edoc2 = $doc2)=~ s{&e(\d);}{[e$1]}g; my $t= XML::Twig->new( keep_spaces => 1); is( $t->parse( $doc1)->sprint, $edoc1, "XML::Twig reuse (run 1: doc1)"); is( $t->parse( $doc2)->sprint, $edoc2, "XML::Twig reuse (run 2: doc2)"); is( $t->parse( $doc1)->sprint, $edoc1, "XML::Twig reuse (run 3: doc1)"); is( $t->parse( $doc1)->sprint, $edoc1, "XML::Twig reuse (run 4: doc1)"); is( $t->parse( $doc2)->sprint, $edoc2, "XML::Twig reuse (run 5: doc2)"); is( $t->parse( $doc2)->sprint, $edoc2, "XML::Twig reuse (run 6: doc2)"); } # some additional coverage { # entity sprint my $tata= "tata content"; spit( "tata.txt", $tata); my %ent_desc=( foo => q{"toto"}, bar => q{SYSTEM "tata.txt"}, baz => q{SYSTEM "tutu.txt" NDATA gif}); my %decl= map { $_ => "" } keys %ent_desc; my $decl_string= join( '', values %decl); my $doc= qq{}; my $t= XML::Twig->parse( $doc); foreach my $ent (sort keys %decl) { is( $t->entity( $ent)->sprint, $decl{$ent}, "sprint entity $ent ($decl{$ent})"); } } { # purge on an element { my $t= XML::Twig->parse( twig_handlers => { e2 => sub { $_->purge } }, q{}); is( $t->root->first_child->tag, 'e3', "purge on the current element"); } { my $t= XML::Twig->parse( twig_handlers => { e2 => sub { $_->prev_sibling->purge } }, q{}); is( $t->root->first_child->tag, 'e2', "purge on an element"); } { my $t= XML::Twig->parse( twig_handlers => { e2 => sub { $_->prev_sibling->purge( $_) } }, q{}); is( $t->root->first_child->tag, 'e3', "purge on an element up to the current element"); } { my $t= XML::Twig->parse( twig_handlers => { e3 => sub { $_->prev_sibling( 'e1')->purge( $_->prev_sibling) } }, q{}); is( $t->root->first_child->tag, 'e3', "purge on an element up to an other element"); } { my $t= XML::Twig->parse( twig_handlers => { e2 => sub { $_[0]->purge_up_to( $_->prev_sibling) } }, q{}); is( $t->root->first_child->tag, 'e2', "purge_up_to"); } } { my $t= XML::Twig->parse( ']>'); is( $t->doctype_name, 'foo', 'doctype_name (with value)'); is( $t->system_id, 'foo.dtd', 'system_id (with value)'); is( $t->public_id, '-//xmltwig//DTD xmltwig test 1.0//EN', 'public_id (with value)'); is( $t->internal_subset, '', 'internal subset (with value)'); } { my $t= XML::Twig->parse( ''); is( $t->doctype_name, '', 'doctype_name (no value)'); is( $t->system_id, '', 'system_id (no value)'); is( $t->public_id, '', 'public_id (no value)'); is( $t->internal_subset, '', 'internal subset (no value)'); } { my $t= XML::Twig->parse( ''); is( $t->doctype_name, 'foo', 'doctype_name (with value)'); is( $t->system_id, 'foo.dtd', 'system_id (with value)'); is( $t->public_id, '', 'public_id (no value)'); is( $t->internal_subset, '', 'internal subset (no value)'); } { my $t= XML::Twig->parse( ']>'); is( $t->doctype_name, 'foo', 'doctype_name (with value)'); is( $t->system_id, '', 'system_id (no value)'); is( $t->public_id, '', 'public_id (no value)'); is( $t->internal_subset, '', 'internal subset (with value)'); } { my $prolog= ']>'; my $doc= ''; my $t= XML::Twig->parse( $prolog . $doc); (my $expected_prolog= $prolog)=~ s{foo}{d}; $t->set_doctype( 'd'); is_like( $t->doctype, $expected_prolog, 'set_doctype'); is_like( $t->sprint, $expected_prolog . $doc); } { # test external entity declaration with SYSTEM _and_ PUBLIC # create external entities my @ext_files= qw( tata1 tata2); foreach my $file (@ext_files) { spit( $file => "content of $file"); } my $doc= q{%bar1;%bar2;]>}; is_like( XML::Twig->parse( $doc)->sprint, $doc, 'external entity declaration with SYSTEM _and_ PUBLIC, regular parse/sprint'); my $out_file= "tmp_test_ext_ent.xml"; open( OUT, ">$out_file") or die "cannot create temp result file '$out_file': $!"; XML::Twig->parse( twig_roots => { elt => sub { $_->print( \*OUT) } }, twig_print_outside_roots => \*OUT, $doc); close OUT; is_like( slurp( $out_file), $doc, 'external entity declaration with SYSTEM _and_ PUBLIC, with twig_roots'); unlink $out_file; open( OUT, ">$out_file") or die "cannot create temp result file '$out_file': $!"; XML::Twig->parse( twig_roots => { elt => sub { $_->print( \*OUT) } }, twig_print_outside_roots => \*OUT, keep_encoding => 1, $doc); close OUT; is_like( slurp( $out_file), $doc, 'external entity declaration with SYSTEM _and_ PUBLIC, with twig_roots and keep_encoding'); unlink @ext_files, $out_file; } { my $doc= q{selt 1selt 2}; my $t= XML::Twig->parse( pretty_print => 'indented', $doc); my $elt_indented = "\n selt 1\n selt 2"; my $elt_not_indented = "selt 1selt 2"; is( $t->first_elt( 'elt')->xml_string, $elt_indented, 'xml_string, indented'); is( $t->first_elt( 'elt')->xml_string( { pretty_print => 'none'} ), $elt_not_indented, 'xml_string, NOT indented'); is( $t->first_elt( 'elt')->xml_string, $elt_indented, 'xml_string, indented again'); } { my $doc=q{ ]>&zzent;}; eval { XML::Twig->new->parse( $doc); }; matches( $@, qr{zznot_there}, "missing SYSTEM entity: file info in the error message ($@)"); matches( $@, qr{zzent}, "missing SYSTEM entity: entity info in the error message ($@)"); } { if( _use( 'HTML::TreeBuilder', 3.13)) { XML::Twig->set_pretty_print( 'none'); my $html=q{

Title

foo
bar

}; my $expected= q{

Title

foo
bar

}; is( XML::Twig->new->safe_parse_html( $html)->sprint, $expected, 'safe_parse_html'); my $html_file= "t/test_3_30.html"; spit( $html_file, $html); is( XML::Twig->new->safe_parsefile_html( $html_file)->sprint, $expected, 'safe_parsefile_html'); if( _use( 'LWP')) { is( XML::Twig->new->safe_parseurl_html( "file:$html_file")->sprint, $expected, 'safe_parseurl_html'); } else { skip( 1, "LWP not available, cannot test safe_parseurl_html"); } unlink $html_file; } else { skip( 3, "HTML::TreeBuilder not available, cannot test safe_parse.*_html methods"); } } { my $dump= XML::Twig->parse( q{text})->_dump; my $sp=qr{[\s|-]*}; matches( $dump, qr{^document $sp doc $sp id="1" $sp elt $sp PCDATA: $sp 'text'\s*}x, "twig _dump"); } { my $dump= XML::Twig->parse( q{]>&foo;})->entity( 'foo')->_dump; is( $dump, q{name => 'foo' - val => 'bar'}, "entity dump"); } { if( $XML::Parser::VERSION > 2.27) { my $t= XML::Twig->parse( q{ ]>&afoo;}); my $non_param_ent= $t->entity( 'afoo'); nok( $non_param_ent->param, 'param on a non-param entity'); my $param_ent= $t->entity( 'bfoo'); ok( $param_ent->param, 'param on a parameter entity'); } else { skip( 2, "cannot use the param method with XML::Parser 2.27"); } } { my $entity_file = "test_3_30.t.ent"; my $missing_file = "not_there"; spit( $entity_file => "entity text"); my $doc= qq{]>&foo;}; ok( eval { XML::Twig->parse( $doc)}, 'doc with missing external SYSTEM ents'); eval { XML::Twig->parse( expand_external_ents => 1, $doc)}; matches( $@, qr{cannot load SYSTEM entity 'bar' from 'not_there': }, 'missing SYSTEM entity'); ok( eval { XML::Twig->parse( $doc)}, 'doc with missing external SYSTEM ents'); my $t= XML::Twig->parse( expand_external_ents => -1, $doc); my $missing_entities= $t->{twig_missing_system_entities}; is( scalar( values %$missing_entities), 1, 'number of missing system entities'); is( (values %$missing_entities)[0]->{name}, 'bar', 'name of missing system entity'); is( (values %$missing_entities)[0]->{sysid}, $missing_file, 'sysid of missing system entity'); eval { XML::Twig->parse( $doc)}; ok( eval { XML::Twig->parse( $doc)}, 'doc with missing external SYSTEM NDATA ents'); unlink( $entity_file); } { my $entity_file = "test_3_30.t.gif"; my $missing_file = "not_there.gif"; spit( $entity_file => "entity text"); my $doc= qq{ ]> }; my $t= XML::Twig->parse( $doc); my $missing_entities= $t->{twig_missing_system_entities}; is( scalar( values %$missing_entities), 1, 'number of missing system entities'); is( $missing_entities->{barn}->name, 'barn', 'name of missing system entity'); is( $missing_entities->{barn}->sysid, $missing_file, 'sysid of missing system entity'); unlink( $entity_file); } { my $doc= q{foo bar baz foobarxyztototatatutu}; my $t= XML::Twig->parse( twig_handlers => { b => sub { $_->erase } }, $doc); is( scalar( $t->descendants( '#TEXT')), 3, 'text descendants, no melding'); $t->normalize; is( scalar( $t->descendants( '#TEXT')), 3, 'text descendants, normalized'); } { my $doc=q{ee1e1-2}; XML::Twig::Elt->init_global_state(); # depending on which modules are available, the state could have been modified my $tmp= "tmp"; open( TMP, ">$tmp") or die "cannot create temp file"; XML::Twig->parse( twig_roots => { e1 => sub { $_->flush( \*TMP) } }, twig_print_outside_roots => \*TMP, $doc); close TMP; my $res= slurp( $tmp); is( $res, $doc, "bug in flush with twig_print_outside_roots"); unlink $tmp; } { # test bug where #default appeared in attributes (RT #27617) my $doc= ''; my $t= XML::Twig->new( map_xmlns => { 'foo' => 'ns2' },)->parse( $doc); ok( grep { $_ eq 'att' } keys %{$t->root->first_child->atts}, 'no #default in attribute names'); } exit; 1; XML-Twig-3.50/t/test_3_39.t0000755000175000017500000000550312346001775015432 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=12; print "1..$TMAX\n"; { my $doc='foo bar fooo baz'; my $t= XML::Twig->parse( $doc); $t->root->split( '(fo+)', e => { att => '$1' } ); is( $t->sprint, 'foo bar fooo baz', 'split, with $1 on attribute value'); $t= XML::Twig->parse( $doc); $t->root->split( '(fo+)', e => { '$1' => 'v$1' } ); is( $t->sprint, 'foo bar fooo baz', 'split, with $1 on attribute name and value'); $t= XML::Twig->parse( $doc); $t->root->split( '(fo+)', '$1' ); is( $t->sprint, 'foo bar fooo baz', 'split, with $1 on tag name'); $t= XML::Twig->parse( $doc); $t->root->split( '(foo+)', '$1', '' ); is( $t->sprint, 'foo bar fooo baz', 'split, with $1 on tag name'); $t= XML::Twig->parse( $doc); $t->root->split( '(fo+)(.*?)(a[rz])', x => { class => 'f' }, '', a => { class => 'x' }); is( $t->sprint, 'foo b
ar fooo baz', 'split, checking that it works with non capturing grouping'); $t= XML::Twig->parse( $doc); $t->root->split( '(fo+)(.*?)(a[rz])', x => { class => '$1' }, '', a => { class => '$3' }); is( $t->sprint, 'foo bar fooo baz', 'split, with $1 and $3 on att value'); } { my $t= XML::Twig->parse( 'e1e2'); is( join( '-', $t->findvalues( '//e')), 'e1-e2', 'findvalues'); } { my $html='

boo

'; my $well_formed = qq{$html}; my $short_doctype = qq{$html}; my $t= XML::Twig->new->parse( $well_formed); is_like( $t->sprint, $well_formed, 'valid xhtml'); if( _use( 'HTML::TreeBuilder')) { my $th= XML::Twig->new->parse_html( $well_formed); is_like( $t->sprint, $well_formed, 'valid xhtml (parsed as html)'); my $t3= XML::Twig->new->parse_html( $short_doctype); is_like( $t3->sprint, $html, 'xhtml without SYSTEM in DOCTYPE (parsed as html, no DOCTYPE output)'); my $t4= XML::Twig->new( output_html_doctype => 1)->parse_html( $short_doctype); is_like( $t4->sprint, $well_formed, 'xhtml without SYSTEM in DOCTYPE (parsed as html, with proper DOCTYPE output)'); } else { skip( 3); } my $t2= XML::Twig->new->safe_parse( $short_doctype); nok( $t2, 'xhtml without SYSTEM in DOCTYPE'); } XML-Twig-3.50/t/test_keep_atts_order.t0000755000175000017500000000456412346001775020135 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; { if( eval 'require Tie::IxHash') { import Tie::IxHash; print "1..7\n"; } else { warn( "Tie::IxHash not available, option keep_atts_order not allowed\n"); print "1..1\nok 1\n"; exit 0; } my $nb_elt=10; my $doc= gen_doc( $nb_elt); my $result= XML::Twig->new( pretty_print => 'indented')->parse( $doc)->sprint; isnt( $result, $doc, "keep_atts_order => 0 (first try)"); $result= XML::Twig->new( keep_atts_order => 1, pretty_print => 'indented')->parse( $doc)->sprint; is( $result, $doc, "keep_atts_order => 1 (first try)"); $result= XML::Twig->new( pretty_print => 'indented')->parse( $doc)->sprint; isnt( $result, $doc, "keep_atts_order => 0 (second try)"); $result= XML::Twig->new( keep_atts_order => 1, pretty_print => 'indented')->parse( $doc)->sprint; is( $result, $doc, "keep_atts_order => 1 (second try)"); $result= XML::Twig->new( keep_atts_order => 1, keep_encoding => 1, pretty_print => 'indented') ->parse( $doc)->sprint; is( $result, $doc, "keep_atts_order => 1, keep_encoding => 1 (first time)"); $result= XML::Twig->new( keep_encoding => 1, pretty_print => 'indented'); $result= XML::Twig->new( keep_atts_order => 1, keep_encoding => 1, pretty_print => 'indented') ->parse( $doc)->sprint; is( $result, $doc, "keep_atts_order => 1, keep_encoding => 1 (second time)"); $result= XML::Twig->new( keep_encoding => 1, pretty_print => 'indented') ->parse( $doc)->sprint; isnt( $result, $doc, " keep_encoding => 1 (second time)"); }; exit 0; sub gen_doc { my( $nb_elt)= @_; my $doc= "\n"; foreach (1..$nb_elt) { $doc .= " $_ + 1 } (0..4) ; while( my( $att, $value)= each %atts) { $doc .= qq{ $att="$value"}; } $doc .= "/>\n"; } $doc .= "\n"; return $doc; } sub randomize { my @list= @_; my $n= @list; foreach (1..10) { my $i= int rand( $n); my $j= int rand( $n); ($list[$i], $list[$j])=($list[$j], $list[$i]) } return @list; } XML-Twig-3.50/t/xmlxpath_test_twig_roots.t0000755000175000017500000001760012346001774021102 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; #use diagnostics; use strict; use Carp; 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; my $DEBUG=0; print "1..12\n"; $|=1; $/= "\n\n"; my $t= XML::Twig::XPath->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 1); $t= XML::Twig::XPath->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 2); $t= XML::Twig::XPath->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 3); $t= XML::Twig::XPath->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 4); $t= XML::Twig::XPath->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 5); $t= XML::Twig::XPath->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 6); $t= XML::Twig::XPath->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 7); $t= XML::Twig::XPath->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 8); $t= XML::Twig::XPath->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 9); $t= XML::Twig::XPath->new( twig_roots => { elt => sub { print RESULT "elt handler called on ", $_->gi, "\n"; }, }, start_tag_handlers => { doc => sub { print RESULT "start tag handler called on ", $_->gi, "\n"; }, }, end_tag_handlers => { doc => sub { print RESULT "end tag handler called on $_[1]\n"; }, }, ); test_twig( $t, 10); # test with doc root as root $t= XML::Twig::XPath->new( twig_roots => { doc => sub { $_->print( \*RESULT); } }); test_twig( $t, 11); # test with elt as root $t= XML::Twig::XPath->new( twig_roots => { elt => sub { $_->print( \*RESULT); } }); test_twig( $t, 12); exit 0; sub test_twig { my( $t, $test_nb)= @_; my $doc= read_doc(); my $expected_result= read_expected_result(); my $result_file= "test_twig_roots.res1"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t->parse( $doc); check_result( $result_file, $test_nb, $expected_result); close RESULT; } sub check_result { my( $result_file, $test_no, $expected_result)= @_; # now check result my $result= read_result( $result_file); if( $result eq $expected_result) { print "ok $test_no\n"; } else { print "nok $test_no\n"; print STDERR "\ntest $test_no:\n", "expected: \n$expected_result\n", "real: \n$result\n"; } } { my $last_doc; my $buffered_result; sub read_doc { local $/="\n\n"; my $doc= ; # if the data starts with #doc then it's a doc, otherwise use the previous one if( $doc=~ /^\s*#\s*doc/) { $doc= clean_data( $doc); $last_doc= $doc; $buffered_result=''; return $doc; } else { $buffered_result= clean_data( $doc); return $last_doc; } } sub read_expected_result { if( $buffered_result) { return $buffered_result; } else { local $/="\n\n"; my $expected_result= ; $expected_result= clean_data( $expected_result); return $expected_result; } } } sub clean_data { my $data= shift; $data=~ s{^\s*#.*\n}{}m; # get rid of comments $data=~ s{\s*$}{}s; # remove trailing spaces (and \n) $data=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines return $data; } sub read_result { my $file= shift; local $/="\n"; open( RESULT, "<$file") or die "cannot read $file: $!"; my @result= grep {m/\S/} ; my $result= join( '', @result); $result=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines close RESULT; unlink $file; return $result; } __DATA__ # doc 1 text subelt text another elt text an other type of element text of subelt # expected_res 1 text subelt text another elt text an other type of element text of subelt # expected_res 2 text subelt text another elt text text of subelt # expected_res 3 text subelt text another elt text an other type of element # doc 2 text subelt text another elt text an other type of element text of subelt # expected_res 4 text subelt text another elt text an other type of element text of subelt # expected_res 5 text subelt text another elt text text of subelt # expected_res 6 text subelt text another elt text an other type of element # doc 3 text subelt text another elt text an other type of element text of subelt # expected_res 7 text subelt text another elt text an other type of element text of subelt # expected_res 8 text subelt text another elt text text of subelt # expected_res 9 text subelt text another elt text an other type of element # doc 4 # expected_res 10 start tag handler called on doc elt handler called on elt end tag handler called on doc # expected_res 11 # expected_res 12 XML-Twig-3.50/t/test1.t0000755000175000017500000002715112346001774014760 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,'t'); use tools; # This just tests a complete twig, no callbacks $|=1; use XML::Twig; my $doc=' ]>
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
'; my $TMAX=97; # don't forget to update! print "1..$TMAX\n"; # test twig creation my $t= new XML::Twig(); ok( $t, 'twig creation'); # test parse $t->parse( $doc, ErrorContext=>2); ok( $t, 'parse'); # test the root my $root= $t->root; etest( $t->root, 'doc', 'doc1', 'root'); # print in a file open( TMP, '>tmp'); select TMP; $t->print(); $root->print(); select STDOUT; $t->print( \*TMP); $root->print( \*TMP); ok( 'ok', "print"); # test the element root and twig functions on the root ok( $root->twig, 'root->twig'); etest( $root->root, 'doc', 'doc1', 'root->root'); # navigation my $section1= etest( $root->first_child, 'section', 'section1', 'first_child'); my $annex= etest( $root->first_child( 'annex'), 'annex', 'annex1', 'first_child( annex)'); etest( $root->last_child, 'annex', 'annex1', 'last_child'); my $section2= etest( $root->last_child( 'section'), 'section', 'section2', 'last_child( section)'); etest( $section2->prev_sibling, 'section', 'section1', 'prev_sibling'); etest( $section1->next_sibling, 'section', 'section2', 'next_sibling'); my $note= etest( $root->next_elt( 'note'), 'note', 'note1', 'next_elt( note)'); etest( $note->root, 'doc', 'doc1', 'root'); ok( $note->twig, 'twig'); etest( $note->twig->root, 'doc', 'doc1', 'twig->root'); # playing with next_elt and prev_elt my $para2= etest( $note->prev_sibling, 'para', 'para2', 'prev_sibling'); etest( $note->prev_elt( 'para'), 'para', 'para2', 'prev_elt( para)'); my $para3= etest( $note->next_sibling, 'para', 'para3', 'next_sibling'); my $paranote1= etest( $note->next_elt( 'para'), 'para', 'paranote1', 'next_elt( para)'); etest( $paranote1->next_elt( 'para'), 'para', 'para3', 'next_elt( para)'); # difference between next_sibling and next_sibling( gi) etest( $para2->next_sibling, 'note', 'note1', 'next_sibling'); etest( $para2->next_sibling( 'para'), 'para', 'para3', 'next_sibling( para)'); # testing in/parent/in_context ok( $paranote1->in( $note), 'in'); ok( $paranote1->in( $section1), 'in'); ok( !$paranote1->in( $section2), 'not in'); ok( $paranote1->in_context( 'note'), 'in_context'); ok( $paranote1->in_context( 'section'), 'in_context'); ok( !$paranote1->in_context( 'intro'), 'not in_context'); etest( $paranote1->parent, 'note', 'note1', 'parent'); # testing list methods (ancestors/children) stest( (join ":", map { $_->id} $paranote1->ancestors), 'note1:section1:doc1', 'ancestors'); stest( (join ":", map { $_->id} $paranote1->ancestors('section')), 'section1', 'ancestors( section)'); stest( (join ":", map { $_->id} $section1->children), 'intro1:title1:para1:para2:note1:para3', 'children'); stest( (join ":", map { $_->id} $section1->children( 'para')), 'para1:para2:para3', 'children( para)'); stest( $paranote1->level, 3, 'level'); # testing attributes my $title1= etest( $root->next_elt( 'title'), 'title', 'title1', 'next_elt( title)'); stest( $title1->id, 'title1', 'id'); stest( $title1->att('id'), 'title1', 'att( id)'); stest( $title1->att('no'), '1', 'att( no)'); $title1->set_att('no', 'Auto'); stest( $title1->att('no'), 'Auto', 'set att( no)'); $title1->set_att('no', '1'); $title1->set_att('newatt', 'newval'); stest( $title1->att('newatt'), 'newval', 'set att( newval)'); $title1->del_att('newatt'); stest( stringifyh( %{$title1->atts}), 'id:title1:no:1', 'del_att'); $title1->set_att('id', 'newid'); stest( $title1->id, 'newid', 'set_att(id)'); stest( $title1->att( 'id'), 'newid', 'set_att(id)'); $title1->set_id( 'title1'); stest( $title1->id, 'title1', 'set_id'); stest( $title1->att( 'id'), 'title1', 'set_id'); stest( stringifyh( %{$title1->atts}), 'id:title1:no:1', 'atts'); $title1->del_atts; stest( $title1->att( 'id'), '', 'del_atts'); $title1->set_atts( { 'no' => '1', 'id' => 'newtitleid'}); stest( stringifyh( %{$title1->atts}), 'id:newtitleid:no:1', 'set_atts'); stest( $title1->id, 'newtitleid', 'id'); stest( $title1->att('id'), 'newtitleid', 'att( id)'); $title1->set_id( 'title1'); # now let's cut and paste $title1->cut; stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1:para3', 'cut (1)'); my $intro1= $section1->first_child( 'intro'); $intro1->cut; stest( (join ":", map { $_->id} $section1->children), 'para1:para2:note1:para3', 'cut (2)'); $intro1->paste( $section1); stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1:para3', 'paste'); $title1->paste( 'first_child', $section2, ); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste( first_child)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'paste'); $title1->paste( $section2); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (3)'); $title1->paste( 'last_child', $section2); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6:title1', 'paste( last_child)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut(4)'); my $intro2= etest( $section2->first_child( 'intro'), 'intro', 'intro2', 'first_sibling( intro)'); $title1->paste( 'after', $intro2); stest( (join ":", map { $_->id} $section2->children), 'intro2:title1:title2:para4:para5:para6', 'paste( after)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (5)'); $title1->paste( 'before', $intro2); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste( before)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (6)'); my $para4= etest( $t->elt_id( 'para4'), 'para', 'para4', 'elt_id'); $title1->paste( 'after', $para4); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:title1:para5:para6', 'paste( after)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (7)'); $title1->paste( 'before', $para4); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:title1:para4:para5:para6', 'paste( before)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (8)'); # now let's mess up the document # let's erase that pesky intro $intro2->erase; stest( (join ":", map { $_->id} $section2->children), 'paraintro3:title2:para4:para5:para6', 'erase'); $para4->delete; stest( (join ":", map { $_->id} $section2->children), 'paraintro3:title2:para5:para6', 'delete'); $t->change_gi( 'paraintro', 'para'); stest( (join ":", map { $_->gi} $section2->children), 'para:title:para:para', 'change_gi'); $para3= etest( $t->elt_id( 'para3'), 'para', 'para3', 'elt_id'); $para3->cut; stest( $section1->text, 'S1 I1S1 I2S1 P1S2 P2Note P1', 'text'); stest( $section1->sprint, '
S1 I1S1 I2S1 P1S2 P2Note P1
', 'sprint'); # let's have a look at those entities # first their names stest( join( ':', $t->entity_names), 'e1:e2:e3', 'entity_list'); # let's look at their content my $e1= $t->entity( 'e1'); stest( $e1->text, '', 'e1 text'); my $e2= $t->entity( 'e2'); stest( $e2->text, '', 'e2 text'); my $e3= $t->entity( 'e3'); stest( $e3->text, '', 'e3 text'); # additionnal erase test $section1= $root->first_child; stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1', 'erase (2)'); $intro1= $section1->first_child( 'intro'); $intro1->erase; stest( (join ":", map { $_->id} $section1->children), 'paraintro1:paraintro2:para1:para2:note1', 'erase (3)'); # new elt test my $new_elt= new XML::Twig::Elt; stest( ref $new_elt, 'XML::Twig::Elt', "new"); my $new_elt1= new XML::Twig::Elt( 'subclass'); stest( ref $new_elt, 'XML::Twig::Elt', "new subclass"); my $new_elt2= new XML::Twig::Elt; stest( ref $new_elt2, 'XML::Twig::Elt', "create no gi"); my $new_elt3= new XML::Twig::Elt( 'elt3'); $new_elt3->set_id( 'elt3'); etest( $new_elt3, 'elt3', 'elt3', "create with gi"); my $new_elt4= new XML::Twig::Elt( 'elt4', 'text of elt4'); ttest( $new_elt4, 'text of elt4', "create with gi and text"); my $new_elt5= new XML::Twig::Elt( 'elt5', 'text of elt5 ', $new_elt4); ttest( $new_elt5, 'text of elt5 text of elt4', "create with gi and content"); my $new_elt6= new XML::Twig::Elt( PCDATA, 'text of elt6'); ttest( $new_elt6, 'text of elt6', "create PCDATA"); # test CDATA my $st1='bold]]>'; my $t1= new XML::Twig; $t1->parse( $st1); sttest( $t1->root, $st1, "CDATA Section"); my $st2='text bold]]> more text'; my $t2= new XML::Twig; $t2->parse( $st2); sttest( $t2->root, $st2, "CDATA Section"); my $st3='bold]]> text'; my $t3= new XML::Twig; $t3->parse( $st3); sttest( $t3->root, $st3, "CDATA Section"); my $st4='textbold]]>more text'; my $t4= new XML::Twig; $t4->parse( $st4); sttest( $t4->root, $st4, "CDATA Section"); my $st5='text more text'; my $t5= new XML::Twig; $t5->parse( $st5); sttest( $t5->root, $st5, "CDATA Section with ]]<"); # test prefix my $st6='textmore text'; my $t6= new XML::Twig; $t6->parse( $st6); $doc= $t6->root; $doc->prefix( 'p1:'); sttest( $t6->root,'p1:textmore text', "prefix doc"); my $el1= $doc->first_child( 'el1'); $el1->prefix( 'p2:'); sttest( $t6->root,'p1:p2:textmore text', "prefix el1"); my $el2= $doc->first_child( 'el2'); my $pcdata= $el2->first_child( PCDATA); $pcdata->prefix( 'p3:'); sttest( $t6->root,'p1:p2:textp3:more text', "prefix pcdata"); exit 0; __END__ XML-Twig-3.50/t/test_new_features_3_22.xml0000644000175000017500000000001412346001775020513 0ustar mrodrigumrodrigu XML-Twig-3.50/t/xmlxpath_tools.pm0000644000175000017500000000057112346001775017151 0ustar mrodrigumrodriguuse strict; use Config; BEGIN { if( eval( 'require XML::Twig::XPath')) { import XML::Twig::XPath; } elsif( $@ =~ m{^cannot use XML::Twig::XPath}) { print "1..1\nok 1\n"; $@=~s{ at.*}{}s; warn "$@\n"; exit; } else { die $@; } } 1; __END__ =head1 SYNOPSYS use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; XML-Twig-3.50/t/zz_dump_config.t0000755000175000017500000000671212346001775016736 0ustar mrodrigumrodrigu#!/usr/bin/perl my $ok; # global, true if the last call to version found the module, false otherwise use Config; warn "\n\nConfiguration:\n\n"; # required warn "perl: $]\n"; warn "OS: $Config{'osname'} - $Config{'myarchname'}\n"; print "\n"; warn "required\n"; warn version( XML::Parser, ''); # We obviously have expat on VMS, but a symbol/logical might # not be set to xmlwf, and when this is the case a # '%DCL-W-IVVERB, unrecognized command verb - check validity and spelling # \XMLWF\' # will be returned. my $skip_xmlwf_test = 0; if ($^O eq 'VMS') { if(`write sys\$output "''xmlwf'"` !~ m/[a-z]+/i) { $skip_xmlwf_test = 1; warn format_warn( 'expat', "Skipping expat (version) test as don't have a symbol for 'xmlwf'."); } } if (! $skip_xmlwf_test) { # try getting this info my $xmlwf_v= `xmlwf -v`; if( $xmlwf_v=~ m{xmlwf using expat_(.*)$}m) { warn format_warn( 'expat', $1, '(required)'); } else { warn format_warn( 'expat', ''); } } print "\n"; # must-have warn "Strongly Recommended\n"; warn version( Scalar::Util, 'for improved memory management'); if( $ok) { unless( defined( &Scalar::Util::weaken)) { warn format_warn( '', 'NOT USED, weaken not available in this version'); warn version( WeakRef); } } else { warn version( WeakRef, 'for improved memory management'); } # encoding warn version( Encode, 'for encoding conversions'); unless( $ok) { warn version( Text::Iconv, 'for encoding conversions'); } unless( $ok) { warn version( Unicode::Map8, 'for encoding conversions'); } print "\n"; # optional warn "Modules providing additional features\n"; warn version( XML::XPathEngine, 'to use XML::Twig::XPath'); warn version( XML::XPath, 'to use XML::Twig::XPath if Tree::XPathEngine not available'); warn version( LWP, 'for the parseurl method'); warn version( HTML::TreeBuilder, 'to use parse_html and parsefile_html'); warn version( HTML::Entities::Numbered, 'to allow parsing of HTML containing named entities'); warn version( HTML::Tidy, 'to use parse_html and parsefile_html with the use_tidy option'); warn version( HTML::Entities, 'for the html_encode filter'); warn version( Tie::IxHash, 'for the keep_atts_order option'); warn version( Text::Wrap, 'to use the "wrapped" option for pretty_print'); print "\n"; # used in tests warn "Modules used only by the auto tests\n"; warn version( Test, ''); warn version( Test::Pod, ''); warn version( XML::Simple, ''); warn version( XML::Handler::YAWriter, ''); warn version( XML::SAX::Writer, ''); warn version( XML::Filter::BufferText, ''); warn version( IO::Scalar, ''); warn version( IO::CaptureOutput, ''); my $zz_dump_config= File::Spec->catfile( t => "zz_dump_config.t"); warn "\n\nPlease add this information to bug reports (you can run $zz_dump_config to get it)\n\n"; warn "if you are upgrading the module from a previous version, make sure you read the\n", "Changes file for bug fixes, new features and the occasional COMPATIBILITY WARNING\n\n"; print "1..1\nok 1\n"; exit 0; sub version { my $module= shift; my $info= shift || ''; $info &&= "($info)"; my $version; if( eval "require $module") { $ok=1; import $module; $version= ${"$module\::VERSION"}; $version=~ s{\s*$}{}; } else { $ok=0; $version= ''; } return format_warn( $module, $version, $info); } sub format_warn { return sprintf( " %-25s: %16s %s\n", @_); } XML-Twig-3.50/t/test_bugs_3_21.t0000755000175000017500000001046612346001775016445 0ustar mrodrigumrodrigu#!/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=25; print "1..$TMAX\n"; { # 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{okNOK}; my $expected= q{okNOK}; 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 &"); } XML-Twig-3.50/t/test_drop_comments.t0000755000175000017500000000174112346001774017625 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; print "1..3\n"; my $xml = < value XML_TEST { my $twig1 = XML::Twig->new(comments => 'keep', keep_spaces => 1); $twig1->parse($xml); ok ($twig1->sprint() =~ //s, 'keep comments'); #print $twig1->sprint, "\n", '-'x80, "\n"; # keeps comments ok $twig1->dispose; } { my $twig2 = XML::Twig->new(comments => 'drop', keep_spaces => 1); $twig2->parse($xml); ok ($twig2->sprint() !~ //s, 'drop comments'); #print $twig2->sprint, "\n", '-'x80, "\n"; # drops comments ok $twig2->dispose; } { my $twig3 = XML::Twig->new(comments => 'keep', keep_spaces => 1); $twig3->parse($xml); ok ($twig3->sprint() =~ //s, 'keep comments'); #print $twig3->sprint, "\n", '-'x80, "\n"; # drops comments!! $twig3->dispose; } exit 0; XML-Twig-3.50/t/xmlxpath_test_with_handlers.t0000755000175000017500000000354712346001774021542 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 7); use XML::Twig::XPath; $|=1; my $doc= ' elt 1 elt 2 elt 3 2 3 2 3 2 3 in_elt6-1 in_elt7-1 in_elt7-2 <:elt id=":elt">yep, that is a valid name ' ; my $t= XML::Twig::XPath->new( twig_handlers => { elt5 => sub { my @res1= $_->findnodes( './elt3/elt4[@att_int="3"] | elt3'); ok( ids( @res1), "elt3-1 - elt4-2 - elt3-2 - elt4-4"); # 1 ok( $_->field( 'elt7[@id="elt7-2"]'), "in_elt7-2"); # 2 ok( $_->findvalue( 'elt7[@id="elt7-2"]'), "in_elt7-2"); # 3 ok( $_->findvalue( 'elt7[preceding-sibling::*[1][self::elt6]]'), "in_elt7-1"); # 4 ok( $_->findvalue( 'elt7[preceding-sibling::elt6]'), "in_elt7-1in_elt7-2"); # 5 ok( $_->findvalue( "elt7"), "in_elt7-1in_elt7-2"); # 6 }, }, ); $t->parse( $doc); ok( ids( $t->findnodes( '//elt3/elt4[@att_int="3"] | //elt3') ), "elt3-1 - elt4-2 - elt3-2 - elt4-4"); # 7 exit 0; sub ids { return join( " - ", map { $_->id } @_); } XML-Twig-3.50/t/test2_2.xml0000644000175000017500000000173612346001774015535 0ustar mrodrigumrodrigu ]>
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_3_26.t0000755000175000017500000001301212346001775015420 0ustar mrodrigumrodrigu#!/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 $DECL=qq{\n}; $DECL=''; my $TMAX=18; print "1..$TMAX\n"; { # testing set_inner_xml my $doc= 'with content

toto

'; my $t= XML::Twig->nparse( $doc); my $inner= '

foo

duh'; $t->first_elt( 'elt')->set_inner_xml( $inner); (my $expected= $doc)=~ s{}{$inner}; is( $t->sprint, $expected, "set_inner_xml"); $t->first_elt( 'elt2')->set_inner_xml( $inner); $expected=~ s{.*}{$inner}; is( $t->sprint, $expected, "set_inner_xml (of an elt with content)"); } { # testing set_inner_html if( !XML::Twig::_use( 'HTML::TreeBuilder', 3.13)) { skip( 4 => "need HTML::TreeBuilder 3.13+ to use set_inner_html method"); } elsif( !XML::Twig::_use( 'LWP')) { skip( 4 => "need LWP to use set_inner_html method"); } else { my $doc= 'a titlepar 1

par 2
after the break'; my $t= XML::Twig->nparse( $doc); my $inner= '

  • foo
  • bar
'; $t->first_elt( 'p')->set_inner_html( $inner); (my $expected= $t->sprint)=~ s{

.*

}{

$inner

}; is( $t->sprint, $expected, "set_inner_html"); $inner= q{2cd title}; $t->first_elt( 'head')->set_inner_html( $inner); $inner=~ s{>$}{/>}; $expected=~ s{.*}{$inner}; $expected=~ s{(]*)(/>)}{$1 $2}g; is( $t->sprint, $expected, "set_inner_html (in head)"); $inner= q{

just a p

}; $t->root->set_inner_html( $inner); $expected= qq{$DECL$inner}; is( $t->sprint, $expected, "set_inner_html (all doc)"); $inner= q{the content of the
body}; $t->first_elt( 'body')->set_inner_html( $inner); $expected= qq{$DECL$inner}; $expected=~ s{
}{
}g; is( $t->sprint, $expected, "set_inner_html (body)"); } } { if( !XML::Twig::_use( "File::Temp")) { skip( 5, "File::Temp not available"); } else { # parsefile_inplace my $file= "test_3_26.xml"; spit( $file, q{nice hey?}); XML::Twig->new( twig_handlers => { foo => sub { $_->set_tag( 'bar')->flush; }}) ->parsefile_inplace( $file); matches( slurp( $file), qr//, "parsefile_inplace"); XML::Twig->new( twig_handlers => { bar => sub { $_->set_tag( 'toto')->flush; }}) ->parsefile_inplace( $file, '.bak'); matches( slurp( $file), qr//, "parsefile_inplace (with backup, checking file)"); matches( slurp( "$file.bak"), qr//, "parsefile_inplace (with backup, checking backup)"); unlink( "$file.bak"); XML::Twig->new( twig_handlers => { toto => sub { $_->set_tag( 'tata')->flush; }}) ->parsefile_inplace( $file, 'bak_*'); matches( slurp( $file), qr//, "parsefile_inplace (with complex backup, checking file)"); matches( slurp( "bak_$file"), qr//, "parsefile_inplace (with complex backup, checking backup)"); unlink( "bak_$file"); unlink $file; } } { if( !XML::Twig::_use( "File::Temp")) { skip( 5, "File::Temp not available"); } elsif( !XML::Twig::_use( "HTML::TreeBuilder")) { skip( 5, "HTML::TreeBuilder not available"); } elsif( !XML::Twig::_use( "LWP")) { skip( 5, "LWP not available"); } elsif( !XML::Twig::_use( "LWP::UserAgent")) { skip( 5, "LWP::UserAgent not available"); } else { # parsefile_html_inplace my $file= "test_3_26.html"; spit( $file, q{foo

this is it

>}); XML::Twig->new( twig_handlers => { p => sub { $_->set_tag( 'h1')->flush; }}) ->parsefile_html_inplace( $file); matches( slurp( $file), qr/

/, "parsefile_html_inplace"); XML::Twig->new( twig_handlers => { h1 => sub { $_->set_tag( 'blockquote')->flush; }}, error_context => 6) ->parsefile_html_inplace( $file, '.bak'); matches( slurp( $file), qr/
/, "parsefile_html_inplace (with backup, checking file)"); matches( slurp( "$file.bak"), qr/

/, "parsefile_html_inplace (with backup, checking backup)"); unlink( "$file.bak"); XML::Twig->new( twig_handlers => { blockquote => sub { $_->set_tag( 'div')->flush; }}) ->parsefile_html_inplace( $file, 'bak_*'); matches( slurp( $file), qr/
/, "parsefile_html_inplace (with complex backup, checking file)"); matches( slurp( "bak_$file"), qr/
/, "parsefile_html_inplace (with complex backup, checking backup)"); unlink( "bak_$file"); unlink $file; } } { use Cwd; if( XML::Twig::_use( "LWP::Simple") && XML::Twig::_use( "LWP::UserAgent")) { my $file = "test_uri"; my $uri = sprintf( "file://%s/%s", getcwd, $file); my $content= "ok"; spit( test_uri => $content); is( XML::Twig::_slurp_uri( $uri), $content, "testing _slurp_uri"); } else { skip( 1, "LWP::Simple or LWP::UserAgent not available"); } } { # test syntax error in XPath predicate (RT #19499) my $t= XML::Twig->nparse( ''); eval { $t->get_xpath( '/*[@!a]'); }; matches( $@, qr/^error in xpath expression/, "syntax error in XPath predicate"); } XML-Twig-3.50/t/xmlxpath_nav.t0000755000175000017500000000247012346001775016427 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; $|=1; my $t= XML::Twig::XPath->new; $t->parse( ' elt 1 elt 2 elt 3 2 3 elt 3 '); my @data= grep { !/^##/ && m{\S} } ; my @exp; my %result; foreach( @data) { chomp; my ($exp, $id_list) = split /\s*=>\s*/ ; $result{$exp}= $id_list; push @exp, $exp; } my $nb_tests= keys %result; print "1..$nb_tests\n"; my $i=1; foreach my $exp ( @exp) { my $expected_result= $result{$exp}; my $result_elt= $t->root->first_child( $exp); my $result= $result_elt ? $result_elt->att( 'id') : 'none'; if( $result eq $expected_result) { print "ok $i\n"; } else { print "nok $i\n"; print STDERR "$exp: expected $expected_result - real $result\n"; } $i++; } exit 0; __DATA__ elt => elt-1 elt[@id="elt-4"] => elt-4 elt[@id="elt-3"] => none *[@att > 1] => elt-2 elt2[2] => elt2-2 ##elt2[./elt2] => elt2-2 elt3 => none XML-Twig-3.50/t/xmlxpath_xpath_cond.t0000755000175000017500000000541312346001775017772 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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; $|=1; my $t= XML::Twig::XPath->new; $t->parse( ' elt 1 elt 2 elt 3 2 3 '); my @data= grep { !/^##/ && m{\S} } ; my @exp; my %result; foreach( @data) { chomp; my ($exp, $id_list) = split /\s*=>\s*/ ; $result{$exp}= $id_list; push @exp, $exp; } my $nb_tests= 2 + keys %result; print "1..$nb_tests\n"; my $i=1; foreach my $exp ( @exp) { my $expected_result= $result{$exp}; my @result= $t->findnodes( $exp); my $result; if( @result) { $result= join ' ', map { $_->id } @result; } else { $result= 'none'; } if( $result eq $expected_result) { print "ok $i\n"; } else { print "nok $i\n"; print STDERR "$exp: expected $expected_result - real $result\n"; } $i++; } my $exp= '//* |//@* | /'; my @result= $t->findnodes( $exp); my @elts= $t->descendants( '#ELT'); # first check the number of results my $result= @result; my $nb_atts=0; foreach (@elts) { $nb_atts+= $_->att_nb; } my $expected_result= scalar @elts + $nb_atts + 1; if( $result == $expected_result) { print "ok $i\n"; } else { print "nok $i\n"; print STDERR "$exp: expected $expected_result - real $result\n"; } $i++; # then check the results (to make sure they are in hte right order) my @expected_results; push @expected_results, "XML::Twig::XPath '" . $t->sprint ."'"; foreach my $elt (@elts) { push @expected_results, ref( $elt) . " '" . $elt->sprint . "'" ; foreach my $att ($elt->att_names) { push @expected_results, qq{XML::Twig::XPath::Attribute '$att="} . $elt->att( $att) . q{"'} ; } } $expected_result= join( "\n ", @expected_results); $result= join( "\n ", map { ref( $_) . " '" . $_->toString ."'" } @result); if( $result eq $expected_result) { print "ok $i\n"; } else { print "nok $i\n"; print STDERR "$exp:\nexpected: $expected_result\n\nreal : $result\n"; } $i++; exit 0; __DATA__ /elt => none //elt => elt-1 elt-2 elt-3 /doc/elt => elt-1 elt-2 /doc/elt[ last()] => elt-2 //elt[@id='elt-1'] => elt-1 //elt[@id="elt-1"] | //elt[@id="elt-2"] | //elt[@id="elt-3"] => elt-1 elt-2 elt-3 //elt[@id="elt-1" or @id="elt-2" or @id="elt-3"] => elt-1 elt-2 elt-3 //elt2[@att_int > 2] => elt2-4 /doc/elt2[ last()]/* => elt2-3 elt2-4 //*[@id="elt2-2"] => elt2-2 /doc/elt2[./elt[@id="elt-3"]] => elt2-1 XML-Twig-3.50/t/test_with_lwp.xml0000644000175000017500000000003712346001774017140 0ustar mrodrigumrodrigu text XML-Twig-3.50/t/xmlxpath_07count.t0000755000175000017500000000114312346001774017135 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 7); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//*[count(BBB) = 2]'); ok($nodes[0]->getName, "DDD"); @nodes = $t->findnodes( '//*[count(*) = 2]'); ok(@nodes, 2); @nodes = $t->findnodes( '//*[count(*) = 3]'); ok(@nodes, 2); ok($nodes[0]->getName, "AAA"); ok($nodes[1]->getName, "CCC"); exit 0; __DATA__ XML-Twig-3.50/t/test_3_41.t0000755000175000017500000001217412346001775015425 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 16; { my $in= 'RoseBlackberryCarrot'; my $expected= 'RoseTomatoBlackberryCarrot'; { my $t = XML::Twig->new( twig_handlers => { '//plant/fruit' => sub { XML::Twig::Elt->new( berry => 'Tomato')->paste( $_); } }) ->parse( $in); is( $t->sprint, $expected, 'paste within handler from new element'); } { my $t = XML::Twig->new( twig_handlers => { '//plant/fruit' => sub { XML::Twig->new->parse( 'Tomato')->root->cut->paste( first_child => $_); } }) ->parse( $in); is( $t->sprint, $expected, 'paste new element from twig within handler from parsed element (cut)'); } { my $t = XML::Twig->new( twig_handlers => { '//plant/fruit' => sub { XML::Twig->new->parse( 'Tomato')->root->paste( $_); } }) ->parse( $in); is( $t->sprint, $in, 'paste new element from twig within handler from parsed element (non cut)'); } } { my $d='foo'; my $calls; XML::Twig->new( twig_roots => { f => 1 }, end_tag_handlers => { e => sub { $calls .= ":e"; }, 'd/e' => sub { $calls .= "d/e" }, }, ) ->parse( $d); is( $calls, 'd/e:e', 'several end_tag_handlers called'); $calls=''; XML::Twig->new( twig_roots => { f => 1 }, end_tag_handlers => { e => sub { $calls .= ":e"; }, 'd/e' => sub { $calls .= "d/e"; return 0; }, }, ) ->parse( $d); is( $calls, 'd/e', 'end_tag_handlers chain broken by false return'); } { my $d='foo'; my $calls; XML::Twig->new( twig_roots => { f => 1 }, ignore_elts => { e => 1 }, end_tag_handlers => { e => sub { $calls .= ":e"; }, 'f/e' => sub { $calls .= "f/e" }, }, ) ->parse( $d); is( $calls, 'f/e:e', 'several end_tag_handlers called with ignore_elts active'); $calls=''; XML::Twig->new( twig_roots => { f => 1 }, ignore_elts => { e => 1 }, end_tag_handlers => { e => sub { $calls .= ":e"; }, 'f/e' => sub { $calls .= "f/e"; return 0; }, }, ) ->parse( $d); is( $calls, 'f/e', 'end_tag_handlers chain with ignore_elts active broken by false return'); } is( XML::Twig->parse( '')->encoding, undef, 'encoding, no xml declaration'); is( XML::Twig->parse( '')->encoding, undef, 'encoding, xml declaration but no encoding given'); is( XML::Twig->parse( '')->encoding, 'utf-8', 'encoding, encoding given'); is( XML::Twig->parse( '')->standalone, undef, 'standalone, no xml declaration'); is( XML::Twig->parse( '')->standalone, undef, 'standalone, xml declaration but no standalone bit'); ok( XML::Twig->parse( '')->standalone, 'standalone, yes'); ok( ! XML::Twig->parse( '')->standalone, 'standalone, no'); { XML::Twig::_set_weakrefs(0); my $t= XML::Twig->parse( ''); $t->root->first_child( 'e')->next_sibling( 'e')->erase; is( $t->sprint, '', 'erase without weakrefs'); XML::Twig::_set_weakrefs(1) } { my $doc=' 1 ... 2 ... '; my $expected= $doc; $expected=~ s{ns1}{cmdsvc}g; $expected=~ s{ns2}{shlsvc}g; my %map= reverse ( cmdsvc => "http://namespace/CommandService", shlsvc => "http://namespace/ShelfService", xsi => "http://www.w3.org/2001/XMLSchema-instance", ); my $x = XML::Twig->new( map_xmlns => { %map }, twig_handlers => { '*[@xsi:type]' => sub { upd_xsi_type( @_, \%map) } }, pretty_print => "indented" ); $x->parse($doc); is( $x->sprint, $expected, 'original_uri'); sub upd_xsi_type { my( $t, $elt, $map)= @_; my $type= $elt->att( 'xsi:type'); my( $old_prefix)= $type=~ m{^([^:]*):}; if( my $new_prefix= $map->{$t->original_uri( $old_prefix)}) { $type=~ s{^$old_prefix}{$new_prefix}; $elt->set_att( 'xsi:type' => $type); } return 1; # to make sure other handlers are called } } XML-Twig-3.50/t/test_bugs_3_18.t0000755000175000017500000006323412346001775016454 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=158; print "1..$TMAX\n"; { #bug with long CDATA # get an accented char in iso-8859-1 my $char_file=File::Spec->catfile('t', "latin1_accented_char.iso-8859-1"); open( CHARFH, "<$char_file") or die "cannot open $char_file: $!"; my $latin1_char=; chomp $latin1_char; close CHARFH; my %cdata=( "01- 1023 chars" => 'x' x 1022 . 'a', "02- 1024 chars" => 'x' x 1023 . 'a', "03- 1025 chars" => 'x' x 1024 . 'a', "04- 1026 chars" => 'x' x 1025 . 'a', "05- 2049 chars" => 'x' x 2048 . 'a', "06- 1023 chars spaces" => 'x' x 1020 . ' a', "07- 1024 chars spaces" => 'x' x 1021 . ' a', "08- 1025 chars spaces" => 'x' x 1022 . ' a', "09- 1026 chars spaces" => 'x' x 1023 . ' a', "10- 2049 chars spaces" => 'x' x 2048 . ' a', "11- 1023 accented chars" => $latin1_char x 1022 . 'a', "12- 1024 accented chars" => $latin1_char x 1023 . 'a', "13- 1025 accented chars" => $latin1_char x 1024 . 'a', "14- 1026 accented chars" => $latin1_char x 1025 . 'a', "15- 2049 accented chars" => $latin1_char x 2048 . 'a', "16- 1023 accented chars spaces" => $latin1_char x 1020 . ' a', "17- 1024 accented chars spaces" => $latin1_char x 1021 . ' a', "18- 1025 accented chars spaces" => $latin1_char x 1022 . ' a', "19- 1026 accented chars spaces" => $latin1_char x 1023 . ' a', "20- 2049 accented chars spaces" => $latin1_char x 2048 . ' a', "21- 511 accented chars" => $latin1_char x 511 . 'a', "22- 512 accented chars" => $latin1_char x 512 . 'a', "23- 513 accented chars" => $latin1_char x 513 . 'a', #"00- lotsa chars" => 'x' x 2000000 . 'a', # do not try this at home # but if you do with a higher number, let me know! ); if( ($] == 5.008) || ($] < 5.006) || ($XML::Parser::VERSION <= 2.27) ) { skip( scalar keys %cdata, "KNOWN BUG in 5.8.0 and 5.005 or with XML::Parser 2.27 with keep_encoding and long (>1024 char) CDATA, " . "see RT #14008 at http://rt.cpan.org/Ticket/Display.html?id=14008" ); } elsif( perl_io_layer_used()) { skip( scalar keys %cdata, "cannot test parseurl when UTF8 perIO layer used " . "(due to PERL_UNICODE being set or -C command line option being used)\n" ); } else { foreach my $test (sort keys %cdata) { my $cdata=$cdata{$test}; my $doc= qq{}; my $twig= XML::Twig->new( keep_encoding => 1)->parse($doc); my $res = $twig->root->first_child->cdata; is( $res, $cdata, "long CDATA with keep_encoding $test"); } } } # subs_text on text with new lines { my $doc= " foo1 \n foo2 "; my $t= XML::Twig->new->parse( $doc); (my $expected= $doc)=~ s{foo}{bar}g; $t->subs_text( qr{foo}, "bar"); is( $t->sprint, $expected, "subs_text on string with \n"); $expected=~ s{ }{ }g; $t->subs_text( qr{ }, q{&ent( " ")} ); if( 0 && $] =~ m{^5.006}) { skip( 1, "known bug in perl 5.6.*: subs_text with an entity matches line returns\n" . " this bug is under investigation\n"); } else { is( $t->sprint, $expected, "subs_text on string with \n"); } } # testing ID processing { # setting existing id to a different value my $t= XML::Twig->new->parse( ''); $t->root->set_id( "i2"); is( id_list( $t), "i2", "changing an existing id"); $t->root->del_id(); is( id_list( $t), "", "deleting an id"); $t->root->del_id(); is( id_list( $t), "", "deleting again an id"); $t->root->set_id( "0"); is( id_list( $t), "0", "changing an existing id to 0"); $t->root->del_id(); is( id_list( $t), "", "deleting again an id"); } { # setting id through the att my $t= XML::Twig->new->parse( ''); $t->root->set_att( id => "i2"); is( fid( $t, "i2"), "i2", "changing an existing id using set_att"); $t->root->set_att( id => "0"); is( fid( $t, "0"), "0", "using set_att with a id of 0"); $t->root->set_atts( { id => "i3" }); is( fid( $t, "i3"), "i3", "using set_atts"); $t->root->set_atts( { id => "0" }); is( fid( $t, "0"), "0", "using set_atts with an if of 0"); } { # setting id through a new element my $t= XML::Twig->new->parse( ''); my $n= $t->root->insert_new_elt( elt => { id => "i2" }); is( id_list( $t), "i1-i2", "setting id through a new element"); $n= $t->root->insert_new_elt( elt => { id => "0" }); is( id_list( $t), "0-i1-i2", "setting id through a new element"); } { # setting ids through a parse my $t= XML::Twig->new->parse( ''); my $elt= XML::Twig::Elt->parse( ''); $elt->paste( $t->root); is( id_list( $t), "0-i1-i2-i3", "setting id through a parse"); } { # test ]]> in text my $doc=q{]]>}; is( XML::Twig->new->parse( $doc)->sprint, $doc, "]]> in char data"); } sub fid { my $elt= $_[0]->elt_id( $_[1]) or return "unknown"; return $elt->att( $_[0]->{twig_id}); } # testing ignore messing up with whitespace handling { my $doc=qq{\n ba\n foo\n bar\n}; my $res; my $t= XML::Twig->new( twig_roots => { elt => sub { $_->ignore; }, elt2 => sub { $res.= $_->text; }, }, start_tag_handlers => { elt2 => sub { $_[0]->ignore if( $_->att( 'ignore')); }, }, ); $t->parse( $doc); is( $res => 'bar', 'checking that ignore and whitespace handling work well together'); } # test on handlers with ns { my $doc=q{ elt with ns att elt with no ns att }; my( $res1, $res2); my $t= XML::Twig->new( map_xmlns => { uri => 'n' }, twig_handlers => { 'n:elt[@n:att="val"]' => sub { $res1 .= $_->text; }, 'n:elt[@att="val"]' => sub { $res2 .= $_->text; }, }, ) ->parse( $doc); is( $res1 => 'elt with ns att', 'twig handler on n:elt[@n:att="val"]'); is( $res2 => 'elt with no ns att', 'twig handler on n:elt[@att="val"]'); } # same with start_tag handlers { my $doc=q{ elt with ns att elt with no ns att }; my( $res1, $res2); my $t= XML::Twig->new( map_xmlns => { uri => 'n' }, start_tag_handlers => { 'n:elt[@n:att="val"]' => sub { $res1 .= $_->att( 'att2'); }, 'n:elt[@att="val"]' => sub { $res2 .= $_->att( 'att2'); }, }, ) ->parse( $doc); is( $res1 => 'ns_att', 'start_tag handler on n:elt[@n:att="val"]'); is( $res2 => 'non_ns_att', 'start_tag handler on n:elt[@att="val"]'); } # same with start_tag handlers and twig_roots { my $doc=q{ elt with ns att elt with no ns att }; my( $res1, $res2); my $t= XML::Twig->new( map_xmlns => { uri => 'n' }, twig_roots => { foo => 1 }, start_tag_handlers => { 'n:elt[@n:att="val"]' => sub { my( $t, $gi, %atts)= @_; $res1 .= $atts{att2}; }, 'n:elt[@att="val"]' => sub { my( $t, $gi, %atts)= @_; $res2 .= $atts{att2}; }, }, ) ->parse( $doc); is( $res1 => 'ns_att', 'start_tag handler on n:elt[@n:att="val"]'); is( $res2 => 'non_ns_att', 'start_tag handler on n:elt[@att="val"]'); } # tests for additional coverage { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { elt => sub { $res.= $_->text}, }); $t->setTwigHandlers(); $t->parse( $doc); is( $res => '', 'setTwigHandlers with no argument'); } { my $doc=q{foobar}; my $res; my $t= XML::Twig->new; $t->setTwigHandlers( { elt => sub { $res.= $_->text}, }); $t->parse( $doc); is( $res => 'foo', 'setTwigHandlers by itself'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { '/doc/elt' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { '/doc/elt' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with an undef path'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { 'doc/elt' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'doc/elt' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with an undef subpath'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { 'elt[@att="baz"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[@att="bak"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[@att="baz"]' => undef, }); $t->setTwigHandlers( { 'elt[@att="bal"]' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with an undef att cond'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { 'elt[@att=~/baz/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[@att=~/bar/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[@att=~/baz/]' => undef, }); $t->setTwigHandlers( { 'elt[@att=~/bas/]' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with undef regexp on att conds'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { 'elt[string()="foo"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[string()="fool"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[string()="foo"]' => undef} ); $t->setTwigHandlers( { 'elt[string()="food"]' => undef} ); $t->parse( $doc); is( $res => '', 'setTwigHandlers with undef string conds'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { 'elt[string()=~/foo/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[string()=~/fool/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { 'elt[string()=~/foo/]' => undef}); $t->setTwigHandlers( { 'elt[string()=~/food/]' => undef}); $t->parse( $doc); is( $res => '', 'setTwigHandlers with undef string regexp conds'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { '*[@att="baz"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { '*[@att="bak"]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { '*[@att="baz"]' => undef, }); $t->setTwigHandlers( { '*[@att="bal"]' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with an undef start att cond'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setTwigHandlers( { '*[@att=~/baz/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { '*[@att=~/bak/]' => sub { $res.= $_->text}, }); $t->setTwigHandlers( { '*[@att=~/baz/]' => undef, }); $t->setTwigHandlers( { '*[@att=~/bal/]' => undef, }); $t->parse( $doc); is( $res => '', 'setTwigHandlers with an undef start att regexp cond'); } { my $doc=q{foobar}; my $res=''; my $t= XML::Twig->new; $t->setStartTagHandlers( { 'elt[@att="baz"]' => sub { $res.= 'not this one'}, }); $t->setStartTagHandlers( { 'elt[@att="bal"]' => sub { $res.= $_->att( 'att') || 'none'}, }); $t->setStartTagHandlers( { 'elt[@att="baz"]' => sub { $res.= $_->att( 'att') || 'none'}, }); $t->parse( $doc); is( $res => 'baz', 'setStartTagHandlers'); } { my $doc=q{titlefoobar}; my $res=''; my $t= XML::Twig->new( twig_handlers => { 'level(2)' => sub { $res .= $_->text;} }) ->parse( $doc); is( $res => 'foobar', 'level cond'); } { my $doc=q{titlefoobar}; my $res=''; my $t= XML::Twig->new( twig_roots => { 'level(2)' => sub { $res .= $_->text;} }) ->parse( $doc); is( $res => 'foobar', 'level cond'); } { my $doc=q{}; my $res=''; XML::Twig->new( pi => 'process', twig_handlers => { '?' => sub { $res.=$_->data } })->parse( $doc); is( $res => 'd1d2', '? (any pi) handler'); } { my $doc=q{foo bar}; my $t= XML::Twig->new->parse( $doc); is( $t->sprint, $doc, 'embedded comments, output asis'); $t->root->first_child( 'elt')->first_child->set_pcdata( 'toto'); is( $t->sprint, 'toto', 'embedded comment removed'); } { my $doc=q{ ] > a &ent; is here }; my $t= XML::Twig->new->parse( $doc); $t->entity_list->add_new_ent( ent2 => 'bar'); my $res= $t->sprint(); is_like( $res, qq{]>} .qq{ a foo is here}, 'new ent, no update dtd'); $res=$t->sprint( updateDTD => 1); is_like( $res, qq{} . qq{]> a foo is here}, 'new ent update dtd' ); } { my $t=XML::Twig->new->parse( ''); $t->{entity_list}= XML::Twig::Entity_list->new; $t->entity_list->add_new_ent( foo => 'bar'); is_like( $t->sprint( update_DTD => 1), ']>', "new entity with update DTD"); } { my $t=XML::Twig->new( keep_encoding => 1)->parse( ''); $t->{entity_list}= XML::Twig::Entity_list->new; $t->entity_list->add_new_ent( foo => 'bar'); is_like( $t->sprint( update_DTD => 1), ']>', "new entity (keep_encoding)with update DTD" ); } { my $dtd= q{ ]> }; my $doc= q{tata}; my $t= XML::Twig->new->parse( $dtd . $doc); is_like( $t->dtd_text, $dtd, "dtd_text"); } { my $t=XML::Twig->new->parse( ''); is( $t->root->first_child( 'elt')->sprint, '', "nav, first pass"); is( $t->root->first_child( 'elt')->sprint, '', "nav, second pass"); is_undef( scalar $t->root->first_child( 'elt')->parent( 'toto'), "undef parent 1"); is_undef( scalar $t->root->parent( 'toto'), "undef parent 2"); is_undef( scalar $t->root->parent(), "undef parent 3"); } { my $t= XML::Twig->new->parse( ''); my $id= $t->root->id; $t->root->add_id(); is( $t->root->id, $id, "add_id on existing id"); my $elt= $t->root->first_child( 'elt'); $elt->cut; $elt->set_id( 'elt1'); is_undef( $t->elt_id( 'elt1'), "id added to elt outside the doc"); $elt->paste( $t->root); is( $t->elt_id( 'elt1')->gi => 'elt', "elt put back in the tree"); # these tests show a bug: the id list is not updated when an element is cut $elt->cut; $elt->del_id; $elt->del_id; # twice to go through a different path $elt->paste( $t->root); is( $t->elt_id( 'elt1')->gi => 'elt', "elt put back in the tree without id"); $elt->del_id; is( $t->elt_id( 'elt1')->gi => 'elt', "deleting an inexisting id which remains in the list"); is( scalar $elt->ancestors_or_self( 'elt'), 1, "ancestors_or_self with cond"); is( scalar $elt->ancestors_or_self(), 2, "ancestors_or_self without cond"); my @current_ns_prefixes= $elt->current_ns_prefixes; is( scalar @current_ns_prefixes, 0, "current_ns_prefixes"); is_undef( $elt->next_elt( $elt), 'next_elt on an empty elt (limited to the subtree)'); is_undef( $elt->next_elt( $elt, 'foo'), 'next_elt on an empty elt (subtree and elt name)'); is_undef( $elt->next_elt( 'foo'), 'next_elt on an empty elt (elt name)'); is_undef( $elt->prev_elt( $elt), 'prev_elt on an empty elt (limited to the subtree)'); is_undef( $elt->prev_elt( $elt, 'foo'), 'prev_elt on an empty elt (subtree and elt name)'); is_undef( $elt->prev_elt( 'foo'), 'prev_elt on an empty elt (elt name)'); is_undef( $elt->next_n_elt( 1, 'foo'), 'next_n_elt'); is_undef( $elt->next_n_elt( 0, 'foo'), 'next_n_elt'); is( $elt->level(), 1, "level"); is( $elt->level( 'elt'), 0, "level"); is( $elt->level( 'doc'), 1, "level"); is( $elt->level( 'foo'), 0, "level"); ok( $elt->in_context( 'doc'), "in_context doc "); ok( $elt->in_context( 'doc', 0), "in_context doc with level (0)"); ok( $elt->in_context( 'doc', 1), "in_context doc with level"); ok( $elt->in_context( 'doc', 2), "in_context doc with level"); nok( $elt->in_context( 'foo'), "in_context foo"); nok( $elt->in_context( 'foo', 0), "in_context foo with level (0)"); nok( $elt->in_context( 'foo', 1), "in_context foo with level"); nok( $elt->in_context( 'foo', 2), "in_context foo with level (0)"); nok( $elt->in_context( 'elt'), "in_context elt"); nok( $elt->in_context( 'elt', 0), "in_context elt with level (0)"); nok( $elt->in_context( 'elt', 1), "in_context elt with level"); nok( $elt->in_context( 'elt', 2), "in_context elt with level (0)"); } { foreach my $doc ( '', 'totototo', 'totototototo', 'tototatatotototo', 'tototiti tututoto', 'toto tututoto', 'toto', 'foototo', 'totototo', '', '', 'toto', '', 'foo', '', '', '', '', '', '', '', '', # this one does not work: nothing in XML::Twig to output stuff after the ï¬inal end tag #'', 'foo', 'foo', 'foo', 'foo', 'foototo', 'foofoo', 'foofoo', 'foofoo', 'foofoo', 'foofoo', 'foofoofoo', 'foofoofoo', 'foo', ) { my $t=XML::Twig->new->parse( $doc); $t->first_elt( 'ERS')->erase; (my $expected= $doc)=~ s{}{}g; is( $t->sprint, $expected, "erase in $doc"); } } { my $t=XML::Twig->new->parse( '

toto

'); my $pcdata= $t->first_elt( '#PCDATA'); $pcdata->split_at( 2); is( $t->sprint => '

toto

', 'split_at'); } { my $doc= q{tototatatu}; my $t= XML::Twig->new->parse( $doc); $t->subs_text( qr/(to)ta/, '&elt(p => $1)ti'); is( $t->sprint,'to

to

titatu
' , 'subs_text'); $t->subs_text( qr/(to)ta/, '&elt(p => $1)ti'); is( $t->sprint,'to

to

titatu
' , 'subs_text (2cd try, same exp)'); $t->subs_text( qr/(ta)/, '&elt(p1 => $1)ti'); is( $t->sprint,'to

to

titatitu
' , 'subs_text cannot merge text with next sibling'); } { my $doc= q{totatu}; my $t= XML::Twig->new->parse( $doc); $t->subs_text( qr/(to)/, '&elt(e => $1)'); is( $t->sprint,'totatu' , 'subs_text (new elt)'); $t->subs_text( qr/(ta)/, '&elt(e => $1)'); is( $t->sprint,'totatu' , 'subs_text (new elt 2)'); $t->subs_text( qr/(t.)/, '&elt(se => $1)'); is( $t->sprint,'totatu' , 'subs_text (several subs)'); } { my $doc= q{totatitu}; my $t= XML::Twig->new->parse( $doc); $t->subs_text( qr/(t[aeiou])/, '$1$1'); is( $t->sprint,'tototatatititutu' , 'subs_text (duplicate string)'); $t->subs_text( qr/((t[aeiou])\2)/, '$2'); is( $t->sprint,'totatitu' , 'subs_text (use \2)'); $t->subs_text( qr/(t[aeiou])/, '$1$1'); is( $t->sprint,'tototatatititutu' , 'subs_text (duplicate string)'); $t->subs_text( qr/(t[aeiou]t[aeiou])/, '&elt( p => $1)'); is( $t->sprint,'

toto

tata

titi

tutu

' , 'subs_text (use \2)'); } { my $doc= q{ toto toto foo bar baz bar baz bar }; my $t= XML::Twig->new->parse( $doc); my $copy= $t->root->copy; is( $copy->sprint, $t->root->sprint, "copy with extra data"); $t->root->insert_new_elt( first_child => a => { '#ASIS' => 1 }, 'a c a'); $copy= $t->root->copy; is( $copy->sprint, $t->root->sprint, "copy with extra data, and asis"); } { my $save= XML::Twig::_weakrefs(); XML::Twig::_set_weakrefs( 0); my $t= XML::Twig->new->parse( 'foo '); $t->root->first_child->cut->DESTROY; $t->root->first_child->cut->DESTROY; is( $t->sprint, '', 'DESTROY'); XML::Twig::_set_weakrefs( $save); } { # test _keep_encoding even with perl > 5.8.0 if( $] < 5.008) { skip( 2 => "testing utf8 flag mongering only needed in perl 5.8.0+"); } else { require Encode; import Encode; my $s="a"; Encode::_utf8_off( $s); nok( Encode::is_utf8( $s), "utf8 flag off"); XML::Twig::Elt::_utf8_ify( $s); if( $] >= 5.008 and $] < 5.010) { ok( Encode::is_utf8( $s), "utf8 flag back on"); } else { nok( Encode::is_utf8( $s), "_utf8_ify is a noop"); } } } { # test keep_encoding is( XML::Twig::Elt::_keep_encoding(), 0, "_keep_encoding not initialized"); XML::Twig->new( keep_encoding => 0); is( XML::Twig::Elt::_keep_encoding(), 0, "_keep_encoding initialized (0)"); XML::Twig->new( keep_encoding => 1); is( XML::Twig::Elt::_keep_encoding(), 1, "_keep_encoding initialized (1)"); XML::Twig->new( keep_encoding => 0); is( XML::Twig::Elt::_keep_encoding(), 0, "_keep_encoding initialized (0)"); } XML-Twig-3.50/t/xmlxpath_13axisparent.t0000755000175000017500000000070712346001775020166 0ustar mrodrigumrodrigu#!/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( '//DDD/parent::*'); ok(@nodes, 4); ok($nodes[3]->getName, "EEE"); exit 0; __DATA__ XML-Twig-3.50/t/test_3_44.t0000755000175000017500000002774612346001775015443 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 86; { my $e= XML::Twig::Elt->new( 'foo'); $e->set_content( { bar => 'baz', toto => 'titi' }); is( $e->sprint, '', 'set_content with just attributes'); } { my $e= XML::Twig::Elt->parse( 't'); $e->set_content( 'x'); is( $e->sprint, 'x', 'set_content on element that contains just text'); $e->first_child( '#PCDATA')->set_content( 'y'); is( $e->sprint, 'y', 'set_content on text element'); $e->set_content( XML::Twig::Elt->new( 'e')); is( $e->sprint, '', 'set_content element on element that contains just text'); $e->set_content( 'z', XML::Twig::Elt->new( 'e')); is( $e->sprint, 'z', 'set_content with 2 elements on element that contains just text'); $e->set_content( ''); is( $e->sprint, '', 'set_content with empty content'); $e->set_content( '#EMPTY'); is( $e->sprint, '', 'set_content with empty content and #EMPTY'); $e->set_content( 'x', 'y'); is( $e->sprint, 'xy', 'set_content with 2 strings'); $e->set_content( '', 'y'); is( $e->sprint, 'y', 'set_content with 2 strings, first one empty'); } { my $t= XML::Twig->parse( ''); my $s= $t->first_elt( 's'); $s->att_to_field( 'a'); is( $s->sprint, '1', 'att_to_field with default name'); $s->field_to_att( 'a'); is( $s->sprint, '', 'field_to_att with default name'); $s->att_to_field( a => 'b'); is( $s->sprint, '1', 'att_to_field with non default name'); $s->field_to_att( b => 'c'); is( $s->sprint, '', 'field_to_att with non default name'); } { my $t= XML::Twig->parse( 'f'); my $r= $t->root; $r->suffix( '&1', 'opt' ); is( $t->sprint, 'f&1', 'suffix, non asis option'); $r->suffix( '&2', 'asis'); is( $t->sprint, 'f&1&2', 'suffix, asis option'); $r->suffix( '&3'); is( $t->sprint, 'f&1&2&3', 'suffix, after a suffix with an asis option'); } { my $t= XML::Twig->parse( 'f'); $t->root->last_child->suffix( '&1', 'opt' ); is( $t->sprint, 'f&1', 'pcdata suffix, non asis option'); $t->root->last_child->suffix( '&2', 'asis'); is( $t->sprint, 'f&1&2', 'pcdata suffix, asis option'); $t->root->last_child->suffix( '&3', 'asis'); is( $t->sprint, 'f&1&2&3', 'pcdata suffix, asis option, after an asis element'); $t->root->last_child->suffix( '&4'); is( $t->sprint, 'f&1&2&3&4', 'pcdata suffix, after a suffix with an asis option'); } { my $t= XML::Twig->parse( 'f'); my $r= $t->root; $r->prefix( '&1', 'opt' ); is( $t->sprint, '&1f', 'prefix, non asis option'); $r->prefix( '&2', 'asis'); is( $t->sprint, '&2&1f', 'prefix, asis option'); $r->prefix( '&3'); is( $t->sprint, '&3&2&1f', 'prefix, after a prefix with an asis option'); } { my $t= XML::Twig->parse( 'f'); $t->root->first_child->prefix( '&1', 'opt' ); is( $t->sprint, '&1f', 'pcdata prefix, non asis option'); $t->root->first_child->prefix( '&2', 'asis'); is( $t->sprint, '&2&1f', 'pcdata prefix, asis option'); $t->root->first_child->prefix( '&3', 'asis'); is( $t->sprint, '&3&2&1f', 'pcdata prefix, asis option, before an asis element'); $t->root->first_child->prefix( '&4'); is( $t->sprint, '&4&3&2&1f', 'pcdata prefix, after a prefix with an asis option'); } { my $weakrefs= XML::Twig::_weakrefs(); XML::Twig::_set_weakrefs(0); my $t= XML::Twig->parse( 'f'); my $e= $t->first_elt( 'e'); XML::Twig::Elt->new( x => 'g')->replace( $e); is( $t->sprint, 'g', 'replace non root element without weakrefs'); XML::Twig::Elt->new( y => 'h')->replace( $t->root); is( $t->sprint, 'h', 'replace root element without weakrefs'); XML::Twig::_set_weakrefs( $weakrefs); } { my $t= XML::Twig->parse( '

foo

barbaz

'); my $r= $t->root; is( $r->children_count, 2, '2 p'); $t->root->first_child->merge( $t->root->last_child); is( $r->children_count, 1, 'merged p'); is( $t->sprint, '

foobarbaz

', 'merged p with extra data'); } { my $t= XML::Twig->parse( '

foo

bazbar

'); my $r= $t->root; is( $r->children_count, 2, '2 p, one with mixed content'); $t->root->first_child->merge( $t->root->last_child); is( $r->children_count, 1, 'merged p, one with mixed content'); is( $t->sprint, '

foobazbar

', 'merged p with extra children in the second element'); } { my $t= XML::Twig->parse( ''); my $r= $t->root; $r->insert_new_elt( first_child => '#PCDATA') foreach 0..1; is( $r->children_count, 2, '2 empty texts'); $r->first_child->merge( $r->last_child); is( $r->children_count, 1, 'merged empty texts, number of children'); is( $t->sprint, '', 'merged empty texts'); } { my $t= XML::Twig->parse( 'a foo afoobar'); my $c=$t->root->copy->subs_text( qr/(foo)/, '&elt( e => "$1")'); is( $c->sprint, 'a foo afoobar', 'subs_text'); $c=$t->root->copy->subs_text( qr/(foo)/, 'X &elt( e => "$1") X'); is( $c->sprint, 'a X foo X aX foo Xbar', 'subs_text'); $c=$t->root->copy->subs_text( qr/(foo)/, 'X &elt( e => "Y $1 Y") X'); is( $c->sprint, 'a X Y foo Y X aX Y foo Y Xbar', 'subs_text'); $c->subs_text( qr/(foo)/, 'X &elt( e => "Y $1 Y") X'); is( $c->sprint, 'a X Y X Y foo Y X Y X aX Y X Y foo Y X Y Xbar', 'subs_text (re-using previous substitution)'); } { my $e= XML::Twig::Elt->new( 'e'); is( $e->att_nb, 0, 'att_nb on element with no attributes'); ok( $e->has_no_atts, 'has_no_atts on element with no attributes'); my $e2= XML::Twig::Elt->new( e => { a => 1 })->del_att( 'a');; is( $e->att_nb, 0, 'att_nb on element with no more attributes'); ok( $e->has_no_atts, 'has_no_atts on element with no more attributes'); is( $e->split_at( 1), '', 'split_at on a non text element'); } SKIP: { skip 'XML::XPath not available', 1 unless XML::Twig::_use( 'XML::XPath'); XML::Twig::_disallow_use( 'XML::XPathEngine'); XML::Twig::_use( 'XML::Twig::XPath'); my $t= XML::Twig::XPath->parse( 'e1e2e3'); is( $t->findvalue( '//e[@a>=3]|//e[@a<=1]'), 'e1e3', 'xpath search with XML::XPath'); } SKIP: { # various tests on _fix_xml skip 'HTML::TreeBuilder not available', 2 unless XML::Twig::_use( 'HTML::TreeBuilder'); my $html= '

&Amp;

'; my $t= HTML::TreeBuilder->new_from_content( $html); local $@='not well-formed (invalid token)'; local $HTML::TreeBuilder::VERSION=3.23; XML::Twig::_fix_xml( $t, \$html); unlike( $html, qr{Amp}, '&Amp with old versions of HTML::TreeBuilder'); like( $html, qr{

parse( 'pre1e1pre2a 1'); is( $t->findvalue( '/d/*[local-name()="e"]'), 'pre1e1pre2', 'local-name()'); } { my $doc= qq{\n\n}; (my $expected= $doc)=~ s{("default">)\n}{$1}; # this space should be discarded my $t= XML::Twig->parse( $doc); is( $t->sprint, $expected, 'xml:space effect on whitespace discarding'); } { my $d= ""; my $got=0; my $t= XML::Twig->new( start_tag_handlers => { e => sub { $got=1; } } ); $t->parse( $d); is( $got, 1, 'setStartTagHandlers'); $t->setStartTagHandlers( { e => sub { $got=2; } }); $t->parse( $d); is( $got, 2, 'setStartTagHandlers changed'); } { my $d= ""; my $got=0; my $st; my $t= XML::Twig->new( start_tag_handlers => { se => sub { $got=1; } }, ignore_elts => { e => \$st }, ); $t->parse( $d); is( $got, 0, 'check that ignore_elts skips element'); is( $st, '', 'check that ignore_elts stores the ignored content'); $st=''; $t->setIgnoreEltsHandler( e => 'discard'); is( $got, 0, 'check that ignore_elts still skips element'); is( $st, '', 'check that ignore_elts now discards the ignored content'); } { my $content= '

here a dodo bird

'; is( XML::Twig::Elt->new( $content)->sprint, $content, 'XML::Twig::Elt->new with litteral content'); } { my $doc= ''; my $doc_no_pi= ''; my $t= XML::Twig->parse( $doc); is( $t->sprint, $doc, 'pi is keep by default'); my $tk= XML::Twig->parse( pi => 'keep', $doc); is( $tk->sprint, $doc, 'pi is keep'); my $td= XML::Twig->parse( pi => 'drop', $doc); is( $td->sprint, $doc_no_pi, 'pi is keep'); my $tp= XML::Twig->parse( pi => 'process', $doc); is( $tp->sprint, $doc, 'pi is process'); foreach my $pi ($t->descendants( '#PI')) { $pi->delete; } is( $t->sprint, $doc, 'pi cannot be cut when pi => keep (by default)'); foreach my $pi ($tk->descendants( '#PI')) { $pi->delete; } is( $tk->sprint, $doc, 'pi cannot be cut when pi => keep'); foreach my $pi ($tp->descendants( '#PI')) { $pi->delete; } is( $tp->sprint, $doc_no_pi, 'pi can be cut when pi => process'); } { my $doc= ''; my $doc_no_comment= ''; my $t= XML::Twig->parse( $doc); is( $t->sprint, $doc, 'comments is keep by default'); my $tk= XML::Twig->parse( comments => 'keep', $doc); is( $tk->sprint, $doc, 'comments is keep'); my $td= XML::Twig->parse( comments => 'drop', $doc); is( $td->sprint, $doc_no_comment, 'comments is keep'); my $tp= XML::Twig->parse( comments => 'process', $doc); is( $tp->sprint, $doc, 'comments is process'); foreach my $comment ($t->descendants( '#COMMENT')) { $comment->delete; } is( $t->sprint, $doc, 'comment cannot be cut when comment => keep (by default)'); foreach my $comment ($tk->descendants( '#COMMENT')) { $comment->delete; } is( $tk->sprint, $doc, 'comment cannot be cut when comment => keep'); foreach my $comment ($tp->descendants( '#COMMENT')) { $comment->delete; } is( $tp->sprint, $doc_no_comment, 'comment can be cut when comment => process'); } { my $d='t1t2

p

'; my $t= XML::Twig->parse( $d); my $p= $t->elt_id( 't'); is( $p->level, 3, 'level'); is( $p->level( 's'), 2, 'level with cond'); is( $p->level( 's[@l]'), 2, 'level with cond on attr'); is( $p->level( 's[@l="2"]'), 1, 'level with more cond on attr'); is( $p->level( 's[@g]'), 0, 'level with unsatisfied more cond on attr'); } { my $d='e1e2e3e4e5f1f1f2'; my $r; my $t; $t= XML::Twig->parse( twig_handlers => { 'e#i' => sub { $r.= $_->text}}, $d); is( $r, 'e1', '# in twig handlers (1 letter id)'); is( $t->findvalue( '//e#i'), 'e1', 'findvalue with # (1 letter id)'); $r=''; $t= XML::Twig->parse( twig_handlers => { 'e#iii' => sub { $r.= $_->text}}, $d); is( $r, 'e5', '# in twig handlers (3 letter id)'); is( $t->findvalue( '//e#iii'), 'e5', 'findvalue with # (3 letter id)'); $r=''; $t= XML::Twig->parse( twig_handlers => { 'e#i2' => sub { $r.= $_->text}}, $d); is( $r, 'e2', '# in twig handlers (letter + digits)'); is( $t->findvalue( '//e#i2'), 'e2', 'findvalue with # (letter + digits)'); $r=''; $t= XML::Twig->parse( twig_handlers => { '*#ff' => sub { $r.= $_->text}}, $d); is( $r, 'f1', '*# in twig handlers'); is( $t->findvalue( '//*#ff'), 'f1', 'findvalue with *#'); } XML-Twig-3.50/t/test_expand_external_entities.dtd0000644000175000017500000000015312346001774022342 0ustar mrodrigumrodrigu ent2 text

"> XML-Twig-3.50/t/test2_2.exp0000644000175000017500000000232112346001774015520 0ustar mrodrigumrodrigu ]>
S1 I1S1 I2S1 TitleS1 P1S2 P2Note P1S1 para 3
S2 introS2 TitleS2 P1S2 P2S2 P3
Annex TitleAnnex P1Annex P2
XML-Twig-3.50/t/xmlxpath_test1.t0000755000175000017500000003214712346001775016707 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; 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; my $DEBUG=0; print "1..114\n"; # This just tests a complete twig, no callbacks $|=1; my $doc=' ]>
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
'; my $i=0; my $failed=0; # test twig creation my $t= XML::Twig::XPath->new; ok( $t, 'twig creation'); # test parse $t->parse( $doc, ErrorContext=>2); ok( $t, 'parse'); ok( ($t->node_cmp( $t->root) == -1), 'cmp twig to root'); ok( ($t->node_cmp( $t) == 0), 'cmp twig to root'); # test the root my $root= $t->root; etest( $t->root, 'doc', 'doc1', 'root'); # print in a file open( TMP, '>tmp'); select TMP; $t->print(); $root->print(); select STDOUT; $t->print( \*TMP); $root->print( \*TMP); ok( 'ok', "print"); # test the element root and twig functions on the root ok( $root->twig, 'root->twig'); etest( $root->root, 'doc', 'doc1', 'root->root'); # navigation my $section1= etest( $root->first_child, 'section', 'section1', 'first_child'); my $annex= etest( $root->first_child( 'annex'), 'annex', 'annex1', 'first_child( annex)'); etest( $root->last_child, 'annex', 'annex1', 'last_child'); my $section2= etest( $root->last_child( 'section'), # 10 'section', 'section2', 'last_child( section)'); etest( $section2->prev_sibling, 'section', 'section1', 'prev_sibling'); etest( $section1->next_sibling, 'section', 'section2', 'next_sibling'); my $note= etest( $root->next_elt( 'note'), 'note', 'note1', 'next_elt( note)'); etest( $note->root, 'doc', 'doc1', 'root'); ok( $note->twig, 'twig'); etest( $note->twig->root, 'doc', 'doc1', 'twig->root'); # playing with next_elt and prev_elt my $para2= etest( $note->prev_sibling, 'para', 'para2', 'prev_sibling'); etest( $note->prev_elt( 'para'), 'para', 'para2', 'prev_elt( para)'); my $para3= etest( $note->next_sibling, 'para', 'para3', 'next_sibling'); my $paranote1= etest( $note->next_elt( 'para'), # 20 'para', 'paranote1', 'next_elt( para)'); etest( $paranote1->next_elt( 'para'), 'para', 'para3', 'next_elt( para)'); # difference between next_sibling and next_sibling( gi) etest( $para2->next_sibling, 'note', 'note1', 'next_sibling'); etest( $para2->next_sibling( 'para'), 'para', 'para3', 'next_sibling( para)'); # testing in/parent/in_context ok( $paranote1->in( $note), 'in'); ok( $paranote1->in( $section1), 'in'); ok( !$paranote1->in( $section2), 'not in'); ok( $paranote1->in_context( 'note'), 'in_context'); ok( $paranote1->in_context( 'section'), 'in_context'); ok( !$paranote1->in_context( 'intro'), 'not in_context'); etest( $paranote1->parent, # 30 'note', 'note1', 'parent'); # testing list methods (ancestors/children) stest( (join ":", map { $_->id} $paranote1->ancestors), 'note1:section1:doc1', 'ancestors'); stest( (join ":", map { $_->id} $paranote1->ancestors('section')), 'section1', 'ancestors( section)'); stest( (join ":", map { $_->id} $section1->children), 'intro1:title1:para1:para2:note1:para3', 'children'); stest( (join ":", map { $_->id} $section1->children( 'para')), 'para1:para2:para3', 'children( para)'); stest( $paranote1->level, 3, 'level'); # testing attributes my $title1= etest( $root->next_elt( 'title'), 'title', 'title1', 'next_elt( title)'); stest( $title1->id, 'title1', 'id'); stest( $title1->att('id'), 'title1', 'att( id)'); stest( $title1->att('no'), '1', 'att( no)'); $title1->set_att('no', 'Auto'); stest( $title1->att('no'), 'Auto', 'set att( no)'); $title1->set_att('no', '1'); $title1->set_att('newatt', 'newval'); stest( $title1->att('newatt'), 'newval', 'set att( newval)'); $title1->del_att('newatt'); stest( stringifyh( %{$title1->atts}), 'id:title1:no:1', 'del_att'); $title1->set_att('id', 'newid'); stest( $title1->id, 'newid', 'set_att(id)'); stest( $title1->att( 'id'), 'newid', 'set_att(id)'); $title1->set_id( 'title1'); stest( $title1->id, 'title1', 'set_id'); stest( $title1->att( 'id'), 'title1', 'set_id'); stest( stringifyh( %{$title1->atts}), 'id:title1:no:1', 'atts'); $title1->del_atts; stest( $title1->att( 'id'), '', 'del_atts'); $title1->set_atts( { 'no' => '1', 'id' => 'newtitleid'}); stest( stringifyh( %{$title1->atts}), 'id:newtitleid:no:1', 'set_atts'); stest( $title1->id, 'newtitleid', 'id'); stest( $title1->att('id'), 'newtitleid', 'att( id)'); $title1->set_id( 'title1'); # now cut and paste $title1->cut; stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1:para3', 'cut (1)'); my $intro1= $section1->first_child( 'intro'); $intro1->cut; stest( (join ":", map { $_->id} $section1->children), 'para1:para2:note1:para3', 'cut (2)'); $intro1->paste( $section1); stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1:para3', 'paste'); $title1->paste( 'first_child', $section2, ); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste( first_child)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'paste'); $title1->paste( $section2); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (3)'); $title1->paste( 'last_child', $section2); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6:title1', 'paste( last_child)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut(4)'); my $intro2= etest( $section2->first_child( 'intro'), 'intro', 'intro2', 'first_sibling( intro)'); $title1->paste( 'after', $intro2); stest( (join ":", map { $_->id} $section2->children), 'intro2:title1:title2:para4:para5:para6', 'paste( after)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (5)'); $title1->paste( 'before', $intro2); stest( (join ":", map { $_->id} $section2->children), 'title1:intro2:title2:para4:para5:para6', 'paste( before)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (6)'); my $para4= etest( $t->elt_id( 'para4'), 'para', 'para4', 'elt_id'); $title1->paste( 'after', $para4); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:title1:para5:para6', 'paste( after)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (7)'); $title1->paste( 'before', $para4); stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:title1:para4:para5:para6', 'paste( before)'); $title1->cut; stest( (join ":", map { $_->id} $section2->children), 'intro2:title2:para4:para5:para6', 'cut (8)'); # now we mess up the document # erase that pesky intro $intro2->erase; stest( (join ":", map { $_->id} $section2->children), 'paraintro3:title2:para4:para5:para6', 'erase'); $para4->delete; stest( (join ":", map { $_->id} $section2->children), 'paraintro3:title2:para5:para6', 'delete'); $t->change_gi( 'paraintro', 'para'); stest( (join ":", map { $_->gi} $section2->children), 'para:title:para:para', 'change_gi'); $para3= etest( $t->elt_id( 'para3'), 'para', 'para3', 'elt_id'); $para3->cut; stest( $section1->text, 'S1 I1S1 I2S1 P1S2 P2Note P1', 'text'); stest( $section1->sprint, '
S1 I1S1 I2S1 P1S2 P2Note P1
', 'sprint'); # have a look at those entities # first their names stest( join( ':', $t->entity_names), 'e1:e2:e3', 'entity_list'); # look at their content my $e1= $t->entity( 'e1'); stest( $e1->text, '', 'e1 text'); my $e2= $t->entity( 'e2'); stest( $e2->text, '', 'e2 text'); my $e3= $t->entity( 'e3'); stest( $e3->text, '', 'e3 text'); # additionnal erase test $section1= $root->first_child; stest( (join ":", map { $_->id} $section1->children), 'intro1:para1:para2:note1', 'erase (2)'); $intro1= $section1->first_child( 'intro'); $intro1->erase; stest( (join ":", map { $_->id} $section1->children), 'paraintro1:paraintro2:para1:para2:note1', 'erase (3)'); # new elt test my $new_elt= new XML::Twig::XPath::Elt; stest( ref $new_elt, 'XML::Twig::XPath::Elt', "new"); my $new_elt1= new XML::Twig::XPath::Elt( 'subclass'); stest( ref $new_elt, 'XML::Twig::XPath::Elt', "new subclass"); my $new_elt2= new XML::Twig::XPath::Elt; stest( ref $new_elt2, 'XML::Twig::XPath::Elt', "create no gi"); my $new_elt3= new XML::Twig::XPath::Elt( 'elt3'); $new_elt3->set_id( 'elt3'); etest( $new_elt3, 'elt3', 'elt3', "create with gi"); my $new_elt4= new XML::Twig::XPath::Elt( 'elt4', 'text of elt4'); ttest( $new_elt4, 'text of elt4', "create with gi and text"); my $new_elt5= new XML::Twig::XPath::Elt( 'elt5', 'text of elt5 ', $new_elt4); ttest( $new_elt5, 'text of elt5 text of elt4', "create with gi and content"); my $new_elt6= new XML::Twig::XPath::Elt( PCDATA, 'text of elt6'); ttest( $new_elt6, 'text of elt6', "create PCDATA"); # test CDATA my $st1='bold]]>'; my $t1= new XML::Twig::XPath; $t1->parse( $st1); sttest( $t1->root, $st1, "CDATA Section"); my $st2='text bold]]> more text'; my $t2= new XML::Twig::XPath; $t2->parse( $st2); sttest( $t2->root, $st2, "CDATA Section"); my $st3='bold]]> text'; my $t3= new XML::Twig::XPath; $t3->parse( $st3); sttest( $t3->root, $st3, "CDATA Section"); my $st4='textbold]]>more text'; my $t4= new XML::Twig::XPath; $t4->parse( $st4); sttest( $t4->root, $st4, "CDATA Section"); my $st5='text more text'; my $t5= new XML::Twig::XPath; $t5->parse( $st5); sttest( $t5->root, $st5, "CDATA Section with ]]<"); # test prefix my $st6='textmore text'; my $t6= new XML::Twig::XPath; $t6->parse( $st6); $doc= $t6->root; $doc->prefix( 'p1:'); sttest( $t6->root,'p1:textmore text', "prefix doc"); my $el1= $doc->first_child( 'el1'); $el1->prefix( 'p2:'); sttest( $t6->root,'p1:p2:textmore text', "prefix el1"); my $el2= $doc->first_child( 'el2'); my $pcdata= $el2->first_child( PCDATA); $pcdata->prefix( 'p3:'); sttest( $t6->root,'p1:p2:textp3:more text', "prefix pcdata"); is( $t6->node_cmp( 1), -1, "compare twig with scalar"); ok( UNIVERSAL::isa( $t->root->getParentNode, 'XML::Twig::XPath'), 'getParentNode on the root'); ok( UNIVERSAL::isa( $t->root->first_child->getParentNode, 'XML::Twig::XPath::Elt'), 'getParentNode on an elt'); eval '$t6->root->node_cmp( []);'; matches( $@, "^unknown node type ", "compare elt with scalar"); my $elt= XML::Twig::XPath::Elt->new( elt => { att1 => 1, att2 => 2 }, "99"); my( $att1, $att2)= $elt->getAttributes; is( $att1->node_cmp( $att2), -1, "attribute comparison"); is( $att2->node_cmp( $att1), 1, "attribute comparison (reverse order)"); is( $att2->node_cmp( $elt), 1, "compare attribute with elt"); is( $att2->node_cmp( $t6), 1, "compare attribute with elt"); is( $elt->node_cmp( $att1), -1, "compare elt with attribute"); is( $att1->node_cmp( $att1), 0, "compare attribute with itself"); is( $elt->node_cmp( $elt), 0, "compare elt with itself"); eval( '$att1->node_cmp( 1)'); matches( $@, "^unknown node type ", "compare att with scalar"); $elt->set_att( att3 => 3); my $att3= XML::Twig::XPath::Attribute->new( $elt => 'att3'); is( $att1->node_cmp( $att3), -1, "attribute comparison"); ok( $att2->to_number == 2, "to_number on att"); ok( $elt->to_number == 99, "to_number on elt"); exit 0; XML-Twig-3.50/t/test_attregexp_cond.t0000755000175000017500000000254512346001775017766 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; my $i=0; my $failed=0; my $TMAX=4; # do not forget to update! print "1..$TMAX\n"; $i++; print "ok $i\n"; # loading my $t= XML::Twig->new( twig_handlers => { 'elt[@att=~/^v/]' => sub { $i++; if( $_->att( 'ok') eq "ok") { print "ok $i\n"; } else { print "NOK $i\n"; # print STDERR "id: ", $_->att( 'id'), "\n"; } }, 'elt[@change=~/^now$/]' => sub { $_[0]->setTwigHandler( 'elt[@att=~/^new/]' => sub { $i++; if( $_->att( 'ok') eq "ok") { print "ok $i\n"; } else { print "NOK $i\n"; # print STDERR "id: ", $_->att( 'id'), "\n"; } }); }, }, ); $t->parse( \*DATA); exit 0; __DATA__ foo q XML-Twig-3.50/t/test_expand_external_entities.t0000755000175000017500000000254512346001775022045 0ustar mrodrigumrodrigu#!/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; my $TMAX=3; print "1..$TMAX\n"; my $xml_file= File::Spec->catfile( "t", "test_expand_external_entities.xml"); my $dtd_file= File::Spec->catfile( "t", "test_expand_external_entities.dtd"); my( $xml, $dtd, $xml_expanded, %ent); { local undef $/; open XML, "<$xml_file" or die "cannot open $xml_file: $!"; $xml= ; close XML; open DTD, "<$dtd_file" or die "cannot open $dtd_file: $!"; $dtd= ; close DTD; } # extract entities while( $dtd=~ m{}gx) { $ent{$1}= $2; } #" # replace in xml ($xml_expanded= $xml)=~ s{&(\w+);}{$ent{$1}}g; { my $t= XML::Twig->new( load_DTD => 1); $t->set_expand_external_entities; $t->parsefile( $xml_file); is( normalize_xml( $t->sprint), normalize_xml( $xml_expanded), "expanded document"); } { my $t= XML::Twig->new( load_DTD => 1, expand_external_ents => 1); $t->parsefile( $xml_file); is( normalize_xml( $t->sprint), normalize_xml( $xml_expanded), "expanded document"); } { (my $xml_no_dtd= $xml_expanded)=~ s{^}{}s; my $t= XML::Twig->new( load_DTD => 1, expand_external_ents => 1, do_not_output_DTD => 1); $t->parsefile( $xml_file); is( normalize_xml( $t->sprint), normalize_xml( $xml_no_dtd), "expanded document"); } exit 0; XML-Twig-3.50/t/xmlxpath_05attrib.t0000755000175000017500000000103612346001774017271 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use Test; plan( tests => 6); use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @ids = $t->findnodes( '//BBB[@id]'); ok(@ids, 2); my @names = $t->findnodes( '//BBB[@name]'); ok(@names, 1); my @attribs = $t->findnodes( '//BBB[@*]'); ok(@attribs, 3); my @noattribs = $t->findnodes( '//BBB[not(@*)]'); ok(@noattribs, 1); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_24namespaces.t0000755000175000017500000001016412346001774020126 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; if( defined $XML::XPathEngine::VERSION && $XML::XPathEngine::VERSION < 0.09) { print "1..1\nok 1\n"; warn "cannot use set_namespace, needs XML::XPathEngine 0.09+ (installed version is $XML::XPathEngine::VERSION)\n"; exit; } plan( tests => 15); my $t= XML::Twig::XPath->new->parse( *DATA); my $node= $t->findvalue( '//attr:node/@attr:findme'); ok( $node, 'someval'); my @nodes; # Do not set namespace prefixes - uses element context namespaces @nodes = $t->findnodes('//foo:foo', $t); # should find foobar.com foos ok( @nodes, 3); @nodes = $t->findnodes('//goo:foo', $t); # should find no foos ok( @nodes, 0); @nodes = $t->findnodes('//foo', $t); # should find default NS foos ok( @nodes, 2); $node= $t->findvalue( '//*[@attr:findme]'); ok( $node, 'attr content'); # Set namespace mappings. $t->set_namespace("foo" => "flubber.example.com"); $t->set_namespace("goo" => "foobar.example.com"); @nodes = $t->findnodes('//foo:foo', $t); # should find flubber.com foos ok( @nodes, 2); @nodes = $t->findnodes('//goo:foo', $t); # should find foobar.com foos ok( @nodes, 3); @nodes = $t->findnodes('//foo', $t); # should find default NS foos ok( @nodes, 2); ok( $t->findvalue('//attr:node/@attr:findme'), 'someval'); ## added to test set_namespace if( ! defined $XML::XPathEngine::VERSION ) { my_skip( 5, "can only test set_strict_namespaces with XML::XPathEngine 0.09+ installed"); } else { my $xml= ' Node 1 Node 2 '; { my $twig = XML::Twig::XPath->new(); $twig->parse( $xml); $twig->set_namespace('example','http://example.com/'); $twig->set_strict_namespaces(1); my $v = $twig->findvalue('//foo'); ok( $v, '', '//foo (strict_namespaces)'); $twig->set_strict_namespaces(0); my $v1 = $twig->findvalue('//foo'); ok( $v1, 'Node 1', '//foo (default behaviour)'); } { my $twig = XML::Twig::XPath->new(); $twig->set_namespace('example','http://example.com/'); $twig->parse( $xml); my $v = $twig->findvalue('//example:foo'); ok( $v, 'Node 1Node 2', '//example:foo'); } { my $twig = XML::Twig::XPath->new(); $twig->parse( $xml); my $v = $twig->findvalue('//foo'); ok( $v, 'Node 1', '//foo'); } { my $twig = XML::Twig::XPath->new(); $twig->parse( $xml); $twig->set_namespace('example','http://example.com/'); my $v = $twig->findvalue('//foo'); ok( $v, 'Node 1', '//foo (default behaviour)'); } } # added to test namespaces on attributes { my $xml= ' Node 1 Node 2 Node 3 Node 4 '; my $twig = XML::Twig::XPath->new(); $twig->parse( $xml); $twig->set_namespace('b','http://example.com/'); ok( $twig->findvalue( '//*[@b:att]'), 'Node 1Node 3', 'namespaces on attributes'); } { my %seen_message; sub my_skip { my( $nb_skip, $message)= @_; $message ||=''; unless( $seen_message{$message}) { warn "\n$message: skipping $nb_skip tests\n"; $seen_message{$message}++; } for (1..$nb_skip) { ok( 1); } } } exit 0; __DATA__ attr content XML-Twig-3.50/t/xmlxpath_15axisfol_sib.t0000755000175000017500000000113212346001774020304 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 6); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '/AAA/BBB/following-sibling::*'); ok(@nodes, 2); ok($nodes[1]->getName, "CCC"); # test document order @nodes = $t->findnodes( '//CCC/following-sibling::*'); ok(@nodes, 3); ok($nodes[1]->getName, "FFF"); exit 0; __DATA__ XML-Twig-3.50/t/test_kwalitee.t0000755000175000017500000000067412346001775016566 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; if( ! $ENV{TEST_AUTHOR} ) { print "1..1\nok 1\n"; warn "Author test. Set \$ENV{TEST_AUTHOR} to a true value to run.\n"; exit; } eval { require Test::More; Test::More->import(); }; if( $@) { print "1..1\nok 1\n"; warn "need test::More installed for this test\n"; exit; } eval { require Test::Kwalitee; Test::Kwalitee->import() }; plan( skip_all => 'Test::Kwalitee not installed; skipping' ) if $@; XML-Twig-3.50/t/test_spaces.t0000755000175000017500000000216412346001774016232 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $/="\n\n"; print "1..3\n"; my $twig=XML::Twig->new( keep_spaces_in => [ 'e']); test( $twig, 1); $twig=XML::Twig->new( keep_spaces_in => [ 'e', 'sub1']); test( $twig, 2); $twig=XML::Twig->new( keep_spaces => 1); test( $twig, 3); sub test { my( $twig, $test_nb)= @_; my $doc= ; chomp $doc; my $expected_res= ; chomp $expected_res; $twig->parse( $doc); my $res= $twig->sprint; $res=~ s/\n+$//; if( $res eq $expected_res) { print "ok $test_nb\n"; } else { print "not ok $test_nb\n"; warn " expected: \n$expected_res\n result: \n$res\n"; } } exit 0; __DATA__ &c;b &c;b &c;b &c; &c;b &c; &c;b &c; &c;b &c; XML-Twig-3.50/t/test_xml_split.xml0000644000175000017500000000055012346001774017316 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_changes.t0000755000175000017500000000037312346001775016365 0ustar mrodrigumrodrigu#!/usr/bin/perl use Test::More; eval 'use Test::CPAN::Changes'; plan skip_all => 'Test::CPAN::Changes required for this test' if $@; plan skip_all => 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.' if ! $ENV{TEST_AUTHOR}; changes_ok(); XML-Twig-3.50/t/test_3_50.t0000755000175000017500000000121212637027341015414 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 2; use utf8; { my $doc=q{titlep 1p 2}; my $out; open( my $out_fh, '>', \$out); my $t= XML::Twig->new ( twig_handlers => { _default_ => sub { $_->flush( $out_fh); } }); $t->parse( $doc); is( $out, $doc, 'flush with _default_ handler'); } { my $doc=q{titlep 1p 2}; my $out; open( my $out_fh, '>', \$out); my $t= XML::Twig->new ( twig_handlers => { 'd' => sub { $_->flush( $out_fh); } }); $t->parse( $doc); is( $out, $doc, 'flush with handler on the root'); } exit; XML-Twig-3.50/t/test_need_io_scalar.t0000755000175000017500000004050112346001775017701 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # tests that require IO::String to run 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; BEGIN { eval "require IO::String"; if( $@) { print "1..1\nok 1\n"; warn "skipping, need IO::String\n"; exit; } else { import IO::String; } } print "1..1778\n"; { my $out1=''; my $fh1= IO::String->new( \$out1); my $out2=''; my $fh2= IO::String->new( \$out2); my $doc='mainignoredcompletelyinignoredcompletely'; my $out= select $fh1; my $t= XML::Twig->new( ignore_elts => { i => 'print' })->parse( $doc); $t->print( $fh2); select $out; is( $out1,'ignoredcompletelyignoredcompletely', 'ignored with print option'); is( $out2,'mainin', 'print after ignored_elts'); } { my $doc='mainignoredcompletelyinignoredcompletely'; my $t= XML::Twig->new( ignore_elts => { i => 'string' })->parse( $doc); is( $t->{twig_buffered_string} || '','ignoredcompletelyignoredcompletely', 'ignored with string option'); is( $t->sprint,'mainin', 'string after ignored_elts (to string)'); } { my $string=''; my $doc='mainignoredcompletelyinignoredcompletely'; my $t= XML::Twig->new( ignore_elts => { i => \$string })->parse( $doc); is( $string,'ignoredcompletelyignoredcompletely', 'ignored with string reference option'); is( $t->sprint,'mainin', 'string after ignored_elts (to string reference)'); } { # test autoflush my $out=''; my $fh= IO::String->new( \$out); my $doc= ""; my $t= XML::Twig->nparse( twig_handlers => { elt => sub { $_->flush( $fh) } }, $doc); is( $out, $doc, "autoflush, no args"); } { my $out=''; my $fh= IO::String->new( \$out); my $doc= ""; my $t= XML::Twig->nparse( twig_handlers => { elt => sub { $_->flush( $fh, empty_tags => "expand") } }, $doc); is( $out, "", "autoflush, no args, expand empty tags"); } { # test bug on comments after the root element RT #17064 my $out=''; my $fh= IO::String->new( \$out); my $doc= q{}; XML::Twig->nparse( $doc)->print( $fh); is( $out, $doc, 'comment after root element'); } { # more tests, with flush this time my $c= ''; my $pi= ''; my @simple_docs= ('', '', 'foo'); my $i=0; my @docs= map { $i++; (my $l= $_)=~ s{#}{$i}g; $i++; (my $t= $_)=~ s{#}{$i}g; map { ("$l$_", "$_$t", "$l$_$t") } @simple_docs; } ( $c, $pi, $c.$pi, $pi.$c, $c.$c, $pi.$pi, $c.$pi.$c, $pi.$c.$pi, $c.$pi.$c.$pi, $pi.$c.$pi.$c, $c.$c.$pi, $c.$pi.$pi) ; foreach my $doc (@docs) { foreach my $options ( { comments => "keep", pi => "keep" }, { comments => "process", pi => "keep" }, { comments => "keep", pi => "process" }, { comments => "process", pi => "process" }, ) { my $options_text= join( ', ', map { "$_ => $options->{$_}" } sort keys %$options); is( XML::Twig->nparse( %$options, $doc)->sprint, $doc, "sprint cpi $options_text $doc"); is( XML::Twig->nparse( %$options, keep_encoding => 1, $doc)->sprint, $doc, "sprint cpi keep_encoding $options_text $doc"); { my $out=''; my $fh= IO::String->new( \$out); XML::Twig->nparse( %$options, $doc)->flush( $fh); is( $out, $doc, "flush cpi $options_text $doc"); } { my $out=''; my $fh= IO::String->new( \$out); XML::Twig->nparse( keep_encoding => 1, %$options, $doc)->flush( $fh); is( $out, $doc, "flush cpi keep_encoding $options_text $doc"); } } } } { my $out=''; my $fh= IO::String->new( \$out); my $doc=q{foo}; my $t= XML::Twig->new( pretty_print => 'indented', empty_tags => 'expand', twig_handlers => { elt => sub { $_[0]->flush( $fh, pretty_print => 'none', empty_tags => 'html' ); }, }, ); $t->{twig_autoflush}=0; $t->parse( $doc); is( $out => q{foo}, 'flush with a pretty_print arg'); is( $t->sprint => qq{\n \n \n \n \n \n\n}, 'flush with a pretty_print arg (checking that option values are properly restored)' ); } { my $out=''; my $fh= IO::String->new( \$out); select $fh; my $doc=q{foo}; my $t= XML::Twig->new( pretty_print => 'indented', empty_tags => 'expand', twig_handlers => { elt => sub { $_[0]->flush( pretty_print => 'none', empty_tags => 'html' ); }, }, ); $t->{twig_autoflush}=0; $t->parse( $doc); select STDOUT; is( $out => q{foo}, 'flush with a pretty_print arg (default fh)'); is( $t->sprint => qq{\n \n \n \n \n \n\n}, 'flush with a pretty_print arg (checking that option values are properly restored) (default fh)' ); } { my $out=''; my $fh= IO::String->new( \$out); select $fh; my $doc=q{foo}; my $t= XML::Twig->new( pretty_print => 'indented', empty_tags => 'expand', twig_handlers => { elt => sub { $_[0]->flush_up_to( $_, pretty_print => 'none', empty_tags => 'html' ); }, }, ); $t->{twig_autoflush}=0; $t->parse( $doc); select STDOUT; is( $out => q{foo}, 'flush with a pretty_print arg (default fh)'); is( $t->sprint => qq{\n \n\n}, 'flush with a pretty_print arg (checking that option values are properly restored)' ); } { my $out=''; my $out2=''; my $out3=''; my $out4=''; my $fh= IO::String->new( \$out); my $fh2= IO::String->new( \$out2); my $fh3= IO::String->new( \$out3); my $fh4= IO::String->new( \$out4); my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none')->parse( ''); $t->print( $fh); is( $out, "", "empty_tags expand"); $t->print( $fh2, empty_tags => 'normal', pretty_print => 'indented' ); is( $out2, "\n \n\n", "print with args"); $t->print( $fh3); is( $out3, "", "print without args"); is( $t->sprint( empty_tags => 'normal'), "", "empty_tags normal"); $t->print( $fh4); is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n\n", "empty_tags expand"); $t->set_pretty_print( 'none'); $t->set_empty_tag_style( 'normal'); } { my $out=''; my $out2=''; my $fh= IO::String->new( \$out); my $fh2= IO::String->new( \$out2); my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none')->parse( ''); $t->root->print( $fh); is( $out, "", "empty_tags expand"); $t->root->print( $fh2, { pretty_print => 'indented' } ); is( $out2, "\n \n\n", "print elt indented"); $out=''; $fh= IO::String->new( \$out); $t->root->print( $fh); is( $out, "", "back to default"); $t->set_pretty_print( 'none'); $t->set_empty_tag_style( 'normal'); } { my $out=''; my $out2=''; my $fh= IO::String->new( \$out); my $fh2= IO::String->new( \$out2); my $t= XML::Twig->new( empty_tags => 'expand', pretty_print => 'none'); $t->parse( '')->flush( $fh); is( $out, "", "empty_tags expand"); $t->parse( '')->flush( $fh2); is( $t->sprint( empty_tags => 'normal'), "", "empty_tags normal"); $out=''; $t->parse( '')->flush( $fh); is( $t->sprint( pretty_print => 'indented', empty_tags => 'normal'), "\n \n\n", "empty_tags expand"); $t->set_pretty_print( 'none'); $t->set_empty_tag_style( 'normal'); } { my $out=''; my $fh= IO::String->new( \$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"); close $fh; $out=""; $fh= IO::String->new( \$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"); $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"); } { my $out=''; my $fh= IO::String->new( \$out); my $t= XML::Twig->new()->parse( q{]>toto}); $t->dtd_print( $fh); is( $out, "\n\n]>\n", "dtd_print"); close $fh; } { my $out=""; my $fh= IO::String->new( \$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{beforefinish}); select STDOUT; is( $out, q{[X]before[Y]finish}, "finish_print"); } package test_handlers; sub new { bless { } } sub recognized_string { return 'recognized_string'; } sub original_string { return 'original_string'; } package main; { my $out=''; my $fh= IO::String->new( \$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'); $out=''; $fh= IO::String->new( \$out); select $fh; XML::Twig::_twig_print( test_handlers->new); select $stdout; close $fh; is( $out, 'recognized_string', 'twig_print_default'); $out=''; $fh= IO::String->new( \$out); select $fh; XML::Twig::_twig_print_end_original( test_handlers->new); select $stdout; close $fh; is( $out, 'original_string', 'twig_print_end_original'); $out=''; $fh= IO::String->new( \$out); select $fh; XML::Twig::_twig_print( test_handlers->new); select $stdout; close $fh; is( $out, 'recognized_string', 'twig_print_end'); } 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'); my @entities= $t->entity_list->list; is( scalar @entities, scalar keys %ents, 'entity_list'); foreach my $ent (@entities) { my $out=''; my $fh= IO::String->new( \$out); my $stdout= select $fh; $ent->print; close $fh; select $stdout; is( normalize_xml( $out), $ent_text{$ent->name}, "print $ent->{name}"); } my $out=''; my $fh= IO::String->new( \$out); my $stdout= select $fh; $t->entity_list->print; close $fh; select $stdout; is( normalize_xml( $out), $ent_text, 'print entity_list'); } { my( $out1, $out2, $out3); my $fh1= IO::String->new( \$out1); my $fh2= IO::String->new( \$out2); my $fh3= IO::String->new( \$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'); is( $out2, 'e

text

', 'print to fh'); is( $out3, 'should be in $out3', 'restoring initial fh'); } { my $doc= 'tatat more'; my $out; my $fh= IO::String->new( \$out); my $t= XML::Twig->new( comments => 'process', pi => 'process')->parse( $doc); $t->flush( $fh); is( $out, $doc, 'flush with cdata'); } { my $out=''; my $fh= IO::String->new( \$out); my $doc='texttext'; my $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, 'texttext', 'twig_print_outside_roots, start/end_tag_handlers, keep_encoding'); close $fh; $out=''; $fh= IO::String->new( \$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, 'texttext', 'twig_print_outside_roots and start_tag_handlers'); } { my $t= XML::Twig->new->parse( ''); eval( '$t->set_output_encoding( "ISO-8859-1");'); if( $@) { skip( 1 => "your system does not seem to support conversions to ISO-8859-1: $@\n"); } else { is( $t->sprint, qq{}, 'creating an output encoding' ); } } { my $out=''; my $fh= IO::String->new( \$out); select $fh; my $doc=' ]>'; my( $expected)= $doc=~ m{()}; XML::Twig->new->parse( $doc)->dtd_print; select STDOUT; is_like( $out, $expected, "dtd_print to STDOUT"); } { my $out=''; my $fh= IO::String->new( \$out); select $fh; my $doc=''; XML::Twig->new( twig_handlers => { elt1 => sub { $_[0]->finish_print; } })->parse( $doc); select STDOUT; is( $out, '', "finish_print to STDOUT"); } { my $out=''; my $fh= IO::String->new( \$out); select $fh; my $doc=''; XML::Twig->new( keep_encoding => 1, twig_handlers => { elt1 => sub { $_[0]->finish_print; } })->parse( $doc); select STDOUT; is( $out, '', "finish_print to STDOUT"); } exit 0; XML-Twig-3.50/t/test_wrapped.t0000755000175000017500000000616612346001774016424 0ustar mrodrigumrodrigu#!/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=13; print "1..$TMAX\n"; unless( XML::Twig::_use( 'Text::Wrap')) { print "1..1\nok 1\n"; warn "skipping: Text::Wrap not available\n"; exit; } while( my $doc= get_doc()) { my $result= XML::Twig->nparse( pretty_print => 'wrapped', $doc)->sprint; my $expected= get_doc(); foreach ($result, $expected) { s{ }{.}g; } is( $result, $expected, ''); } XML::Twig::Elt->set_wrap(0); is( XML::Twig::Elt->set_wrap(1), 0, "set_wrap - 1"); is( XML::Twig::Elt->set_wrap(1), 1, "set_wrap - 2"); is( XML::Twig::Elt->set_wrap(0), 1, "set_wrap - 3"); is( XML::Twig::Elt->set_wrap(0), 0, "set_wrap - 4"); is( XML::Twig::Elt::set_wrap(1), 0, "set_wrap - 5"); is( XML::Twig::Elt::set_wrap(1), 1, "set_wrap - 6"); is( XML::Twig::Elt::set_wrap(0), 1, "set_wrap - 7"); is( XML::Twig::Elt::set_wrap(0), 0, "set_wrap - 8"); sub get_doc { local $/="\n\n"; my $doc= ; if( $doc) { $doc=~ s{\n\n}{\n}; $doc=~ s/\{([^}]*)\}/$1/eeg; } return $doc; } __DATA__ {"foo" x 40} foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo {"foo" x 80} foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof oofoofoofoofoofoofoofoofoofoofoo
{"foo" x 40}
foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo
{"foo " x 40} {"bar " x 40} foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar {"foo " x 40}{ "aaa" x 60}{ "foo "x20 } {"bar " x 40} foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafoo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar XML-Twig-3.50/t/test_3_40.t0000755000175000017500000003475112346001774015430 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=96; print "1..$TMAX\n"; { my $d="titlep 1 p 2"; is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_spaces => 1, $d)), 1, 'space prevents indentation'); is( lf_in_t( XML::Twig->parse( pretty_print => 'indented', discard_all_spaces => 1, $d)), 5, 'discard_all_spaces restores indentation'); } sub lf_in_t { my($t)= @_; my @lfs= $t->sprint=~ m{\n}g; return scalar @lfs; } { my $d=''; my @tests= ( [ 't1|t2', HN => 't1t2' ], [ 't1|t2|t3[@att="a|b"]', HN => 't1t2t3-1' ], [ 't1|t2|t3[@att!="a|b"]', HN => 't1t2t3-2t3-3' ], [ 't1|level(1)', H => 't1t1t2t3-1t3-2t3-3' ], [ 't1|level(2)', H => 't1t4' ], [ 't1|_all_', H => 't1t1t2t3-1t3-2t4t3-3d'], [ qr/t[12]/ . '|t3/t4', H => 't1t2t4' ], [ 't3[@a2="a|b"]', HN => 't3-2' ], [ 't3[@a2="a|b"]|t3|t3/t4', H => 't3-1t3-2t3-2t4t3-3' ], ); foreach my $test (@tests) { my $nb=0; my $ids=''; my( $trigger, $test_cat, $expected_ids)= @$test; my $handlers= $test_cat =~ m{H} ? { $trigger => sub { $ids.=$_->id; 1; } } : {}; my $t= XML::Twig->new( twig_handlers => $handlers )->parse( $d); is( $ids, $expected_ids, "(H) trigger with alt: '$trigger'"); my $uniq_ids= join '', sort $expected_ids=~m{(t\d(?:-\d)?)}g; if( $test_cat =~ m{X}) { (my $xpath= "//$trigger")=~ s{\|t}{|//t}g; is( join( '', map { $_->id } $t->findnodes( $xpath)), $uniq_ids, " (X) path with |: '$trigger'"); } if( $test_cat =~ m{N}) { is( join( '', map { $_->id } $t->root->children( $trigger)), $uniq_ids, "(N)navigation with |: '$trigger'"); } } } { my $t1= XML::Twig->parse( ''); is( XML::Twig->active_twig()->root->id, 'd1', 'active_twig, one twig'); my $t2= XML::Twig->parse( ''); is( XML::Twig->active_twig()->root->id, 'd2', 'active_twig, second twig'); } { eval { XML::Twig->new(error_context => 1)->parse( $0); }; matches( $@, "you seem to have used the parse method on a filename", 'parse on a file name'); } { my $got; XML::Twig->parse( twig_handlers => { 'e[@a]' => sub { $got .= $_->id; } }, ''); is( $got, 'i1i3', 'bare attribute in handler condition'); } if( $] > 5.008) { my $doc= q{]>&ext;}; ok( XML::Twig->parse( expand_external_ents => -1, $doc), 'failsafe expand_external_ents'); } else { skip( 1, 'not tested under perl < 5.8'); } { my $t=XML::Twig->parse( q{e11e21e12}); is( join( ':', $t->findvalues( [$t->root->children], "./e1")), 'e11:e12', 'findvalues on array'); } { my $t=XML::Twig->parse( ""); $t->set_encoding( "UTF-8"); is( $t->sprint, qq{\n}, 'set_encoding without XML declaration'); } { my $t=XML::Twig->parse( ""); $t->set_standalone( 1); is( $t->sprint, qq{\n}, 'set_standalone (yes) without XML declaration'); } { my $t=XML::Twig->parse( ""); $t->set_standalone( 0); is( $t->sprint, qq{\n}, 'set_standalone (no) without XML declaration'); } { my $t=XML::Twig->parse( ""); nok( $t->xml_version, 'xml_version with no XML declaration'); $t->set_xml_version( 1.1); is( $t->sprint, qq{\n}, 'set_xml_version without XML declaration'); is( $t->xml_version, 1.1, 'xml_version after being set'); } { my $t= XML::Twig->new; is( $t->_dump, "document\n", '_dump on an empty twig'); } { my $t=XML::Twig->parse( pretty_print => 'none', 'foobar'); $t->root->field_to_att( 'f[@a="b"]', 'g'); is( $t->sprint, 'foo', 'field_to_att on non-simple condition'); $t->root->att_to_field( g => 'gg'); is( $t->sprint, 'barfoo', 'att_to_field with att != field'); } { my $t=XML::Twig->parse( ''); $t->root->wrap_in( 'nroot'); is( $t->sprint, '', 'wrapping the root'); } { my $t=XML::Twig->new; XML::Twig::_set_weakrefs(0); my $doc='\n texttext more text foo\n more'; $t->parse( $doc); $doc=~ s{\n }{}; # just the first one is( $t->sprint, $doc, 'parse with no weakrefs'); $t->root->insert_new_elt( first_child => x => 'text'); $doc=~ s{}{text}; is( $t->sprint, $doc, 'insert first child with no weakrefs'); $t->root->insert_new_elt( last_child => x => 'text'); $doc=~ s{}{text}; is( $t->sprint, $doc, 'insert last child with no weakrefs'); $t->root->wrap_in( 'dd'); $doc=~ s{}{
}; $doc=~s{}{
}; is( $t->sprint, $doc, 'wrap with no weakrefs'); $t->root->unwrap; $doc=~s{}{}g; is( $t->sprint, $doc, 'unwrap with no weakrefs'); my $new_e= XML::Twig::Elt->new( ee => { c => 1 }, 'ee text'); $new_e->replace( $t->root->first_child( 'e')); $doc=~ s{}{ee text}; is( $t->sprint, $doc, 'replace with no weakrefs'); XML::Twig::_set_weakrefs(1); } { my $t= XML::Twig->new( no_expand => 1); XML::Twig::_set_weakrefs(0); my $doc=']> bar &bar; bar&bar;&foo; &bar; bar &foo;&bar; na &foo;'; $t->parse( $doc); (my $got= $t->sprint)=~ s{\n}{}g; is( $got, $doc, 'external entities without weakrefs'); XML::Twig::_set_weakrefs(1); } { XML::Twig::_set_weakrefs(0); { my $t= XML::Twig->new; undef $t; } ok( 1, "DESTROY doesn't crash when weakrefs is off"); XML::Twig::_set_weakrefs(1); } { my $doc= 'foobarbar'; my( $got1, $got2); XML::Twig->new( twig_handlers => { e1 => sub { $_->parent->set_att( get1 => 1); }, e2 => sub { $_->parent->set_att( '#get2' => 1); }, '[@get1]' => sub { $got1 .= 'a' . $_->id; }, '[@#get2]' => sub { $got2 .= 'a' . $_->id; }, 'e[@get1]' => sub { $got1 .= 'b' . $_->id; }, 'e[@#get2]' => sub { $got2 .= 'b' . $_->id; }, }, ) ->parse( $doc); is( $got1, 'be1ae1', 'handler on bare attribute'); is( $got2, 'be3ae3', 'handler on private (starting with #) bare attribute'); } { my $t=XML::Twig->parse( 'foo'); my $root= $t->root; ok( $root->closed, 'closed on completely parsed tree'); ok( $root->_extra_data_before_end_tag, '_extra_data_before_end_tag (success)'); nok( $root->first_child->_extra_data_before_end_tag, '_extra_data_before_end_tag (no data)'); } { my $t= XML::Twig->parse( pi => 'process', ''); is( $t->first_elt( '#PI')->pi_string, '', 'pi_string with empty data'); } { my $t= XML::Twig->parse( ''); is( ids( $t->root->children( '.a')), 'e1:f1', 'nav on class'); } { my $t=XML::Twig->parse( 'foobarfoobar123'); is ( ids( $t->root->children( 'e[string()="foo"]')), 'e1', 'navigation condition using string() ='); is ( ids( $t->root->children( 'e[string()=~/foo/]')), 'e1:e3', 'navigation condition using string() =~'); is ( ids( $t->root->children( 'e[string()!~/foo/]')), 'e2:e4', 'navigation condition using string() !~'); is ( ids( $t->root->children( 'e[string()!="foo"]')), 'e2:e3:e4', 'navigation condition using string() !='); is ( ids( $t->root->children( 'e[string()]')), 'e1:e2:e3', 'navigation condition using bare string()'); is ( ids( $t->root->findnodes( './e[string()="foo"]')), 'e1', 'xpath condition using string() ='); is ( ids( $t->root->findnodes( './e[string()=~/foo/]')), 'e1:e3', 'xpath condition using string() =~'); is ( ids( $t->root->findnodes( './e[string()!~/foo/]')), 'e2:e4', 'xpath condition using string() !~'); is ( ids( $t->root->findnodes( './e[string()!="foo"]')), 'e2:e3:e4', 'xpath condition using string() !='); is ( ids( $t->root->findnodes( './e[string()]')), 'e1:e2:e3', 'xpath condition using bare string()'); is( ids( $t->root->children( 'n[string()=2]')), 'n2', 'navigation string() ='); is( ids( $t->root->children( 'n[string()!=2]')), 'n1:n3', 'navigation string() !='); is( ids( $t->root->children( 'n[string()>2]')), 'n3', 'navigation string() >'); is( ids( $t->root->children( 'n[string()>=2]')), 'n2:n3', 'navigation string() >='); is( ids( $t->root->children( 'n[string()<2]')), 'n1', 'navigation string() <'); is( ids( $t->root->findnodes( './n[string()=2]')), 'n2', 'xpath string() ='); is( ids( $t->root->findnodes( './n[string()!=2]')), 'n1:n3', 'xpath string() !='); is( ids( $t->root->findnodes( './n[string()>2]')), 'n3', 'xpath string() >'); is( ids( $t->root->findnodes( './n[string()>=2]')), 'n2:n3', 'xpath string() >='); is( ids( $t->root->findnodes( './n[string()<2]')), 'n1', 'xpath string() <'); is( ids( $t->root->findnodes( './n[string()<=2]')), 'n1:n2', 'xpath string() <='); } { my $got; my $t=XML::Twig->parse( twig_handlers => { d => sub { $got .="wrong"; }, 'd[@id]' => sub { $got .= "ok"; 0 }, }, '' ); is( $got, 'ok', 'returning 0 prevents the next handler to be called'); } { my $d=q{foo

fooblank


}; my $expected=qq{\n \n foo\n \n \n

fooblank

\n
\n
}; XML::Twig::_indent_xhtml( \$d); is( $d, $expected, '_indent_xhtml'); } { my $d='c'; my @handlers= ( '/d/e[@a="a" or @b="b"]', '/d/e[@a="a" or @b="c"]|e', '/d/e[@a="a"]', '/d/e[@b="b"]', '/d/e', 'd/e[@a="a" and @b="b"]', 'd/e[@a="a"]', 'd/e[@b="b"]', 'd/e', 'e[@a="a" or @b="b"]', 'e[@b="b" or @a="a"]', 'e[@a="a"]|f', 'e[@b="b"]', 'e', qr/e|f/, qr/e|f|g/, 'level(1)', ); my $t= XML::Twig->new(); for my $stem ( 1, 100) { my $i= $stem; my $expected= join '', ($stem..$stem+$#handlers); my $got; $t->setTwigHandlers( { map { $_ => sub { $got .= $i++; } } @handlers }); $t->parse( $d); is( $got, $expected, 'handler order'); } } { my $t=XML::Twig->parse( ""); $t->{twig_dtd}=""; is( $t->doctype(UpdateDTD => 1), "\n", 'doctype with an updated DTD'); } { my $t=XML::Twig->parse( ''); $t->elt_accessors( 'e', 'e'); $t->elt_accessors( { e2 => 'e[2]', se => 'se', sea => 'se[@a]' }); my $root= $t->root; is( $root->e->id, 'e1', 'accessor, no alias, scalar context'); my $e2= ($root->e)[-1]; is( $e2->id, 'e2', 'accessor no alias, list context'); $e2= $root->e2; is( $e2->id, 'e2', 'accessor alias, list context'); is( $e2->se->id, 'se1', 'accessor alias, scalar context'); is( $e2->sea->id, 'se2', 'accessor, with complex step, alias, scalar context'); } { my $t=XML::Twig->new( elt_accessors => [ 'e', 'se' ]) ->parse( ''); my $root= $t->root; is( $root->e->id, 'e1', 'accessor (created in new), no alias, scalar context'); my $se= ($root->e)[-1]->se; is( $se->id, 'se1', 'accessor (created in new) no alias, scalar context, 2'); } { my $t=XML::Twig->new( elt_accessors => { e2 => 'e[2]', se => 'se', sea => 'se[@a]' }) ->parse( ''); my $e2= $t->root->e2; is( $e2->id, 'e2', 'accessor (created in new) alias, list context'); is( $e2->se->id, 'se1', 'accessor (created in new) alias, scalar context'); is( $e2->sea->id, 'se2', 'accessor (created in new), with complex step, alias, scalar context'); } { my $doc= ']>'; my $t= XML::Twig->parse( do_not_output_DTD => 1, $doc); is( $t->sprint, qq{\n}, 'do_not_output_DTD'); } { my $t= XML::Twig->parse( no_prolog => 1, ']>'); is( $t->sprint, qq{}, 'no_prolog'); } { my $t= XML::Twig->parse( ']>'); is( $t->sprint, qq{\n\n]>\n}, 'no_prolog'); } { my $e= XML::Twig::Elt->new( 'e'); $e->set_empty; is( $e->sprint, '', 'set_empty with no value'); $e->set_empty( 0); is( $e->sprint, '', 'set_empty(0)'); $e->set_empty; is( $e->sprint, '', 'set_empty with no value'); $e->set_empty( 1); is( $e->sprint, '', 'set_empty(1'); $e->set_empty; is( $e->sprint, '', 'set_empty with no value'); $e->set_empty( 1); is( $e->sprint, '', 'set_empty(1)'); my $e2= XML::Twig::Elt->parse( ''); $e2->set_not_empty(); is( $e2->sprint, '', 'set_not_empty'); ok( ! $e2->closed, 'closed on an orphan elt'); } { my $t= XML::Twig->parse( ''); my $l2= $t->first_elt( 'l2'); my $l4= $t->first_elt( 'l4'); $l2->cut; $l4->cut; is( $l4->_root_through_cut->tag, 'd', '_root_through_cut'); is( $l4->_inherit_att_through_cut( 'a', 'd'), 'd', '_inherit_att_through_cut'); } { my $s= "foo"; is( XML::Twig::_to_utf8( 'iso-8859-1', $s), $s, 'trivial test of _to_utf8'); } XML-Twig-3.50/t/test_with_lwp_not_wf.xml0000644000175000017500000000003612346001775020514 0ustar mrodrigumrodrigu text XML-Twig-3.50/t/xmlxpath_30lang.t0000755000175000017500000000100412346001775016717 0ustar mrodrigumrodrigu#!/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( keep_spaces => 1)->parse( \*DATA); ok( $t); my @en = $t->findnodes( '//*[lang("en")]'); ok(@en, 2); my @de = $t->findnodes( '//content[lang("de")]'); ok(@de, 1); exit 0; __DATA__ Here we go... und hier deutschsprachiger Text :-) XML-Twig-3.50/t/test2.t0000755000175000017500000000422312346001774014754 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; # This tests the doctype and DTD access functions $|=1; use XML::Twig; use Cwd; $0 =~ s!\\!/!g; my ($DIR,$PROG) = $0 =~ m=^(.*/)?([^/]+)$=; $DIR =~ s=/$== || chop($DIR = cwd()); chdir $DIR; my $i=0; my $failed=0; my $TMAX=15; # don't forget to update! print "1..$TMAX\n"; # test twig creation my $t= new XML::Twig(); ok( $t, 'twig creation'); # first test an internal DTD my $in_file= "test2_1.xml"; my $res_file= "test2_1.res"; my $exp_file= "test2_1.exp"; # test parse no dtd info required $t->parsefile( $in_file, ErrorContext=>2); ok( $t, 'parse'); open( RES, ">$res_file") or die "cannot open $res_file:$!"; $t->print( \*RES); close RES; ok( $res_file, $exp_file, "flush"); $res_file= 'test2_2.res'; $exp_file= 'test2_2.exp'; open( RES, ">$res_file") or die "cannot open $res_file:$!"; $t->print( \*RES, Update_DTD => 1); close RES; ok( $res_file, $exp_file, "flush"); $t= new XML::Twig(); ok( $t, 'twig creation'); $in_file= "test2_2.xml"; $res_file= "test2_3.res"; $exp_file= "test2_3.exp"; $t->parsefile( $in_file, ErrorContext=>2); ok( $t, 'parse'); open( RES, ">$res_file") or die "cannot open $res_file:$!"; my $e2=new XML::Twig::Entity( 'e2', 'entity2'); my $entity_list= $t->entity_list; $entity_list->add( $e2); my $e3=new XML::Twig::Entity( 'e3', undef, 'pic.jpeg', 'JPEG'); $entity_list= $t->entity_list; $entity_list->add( $e3); $t->print( \*RES, Update_DTD => 1); close RES; ok( $res_file, $exp_file, "flush"); my $dtd= $t->dtd; ok( !$dtd, 'dtd exits'); $t= new XML::Twig(LoadDTD=>1); ok( $t, 'twig creation'); $t->parsefile( $in_file, ErrorContext=>2, ); $dtd= $t->dtd; ok( $dtd, 'dtd not found'); my @model= sort keys %{$dtd->{model}}; stest( stringify( @model), 'doc:intro:note:para:section:title', 'element list'); stest( $t->model( 'title'), '(#PCDATA)', 'title model'); mtest( $t->model( 'section'), '\(intro\?,\s*title,\s*\(para|note\)+\)', 'section model'); stest( $t->dtd->{att}->{section}->{id}->{type}, 'ID', 'section id type'); stest( $t->dtd->{att}->{section}->{id}->{default}, '#IMPLIED', 'section id default'); exit 0; XML-Twig-3.50/t/test_pos.t0000755000175000017500000000275512346001774015563 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; $|=1; # test for the various conditions in navigation methods use XML::Twig; my $t= XML::Twig->new; $t->parse( ' an element an element an element an element an element an element an element '); my @data=; my @data_without_comments= grep { !m{^\s*(#.*)?$} } @data; my @test= map { s{\#.*$}{}; $_ } @data_without_comments; #my @test= map { s{#.*$}{}; $_ } grep { !m{^\s*(#.*)?$} } ; my $nb_test= @test; print "1..$nb_test\n"; my $i=1; foreach my $test (@test) { my( $id, $exp, $expected_pos)= split /\t+/, $test; chomp $expected_pos; $exp= '' if( $exp eq '_'); test( $i++, $id, $exp, $expected_pos); } sub test { my( $i, $id, $exp, $expected_pos)= @_; my $elt= $t->elt_id( $id); my $pos= $elt->pos( $exp); if( $pos == $expected_pos) { print "ok $i\n"; } else { print "not ok $i\n"; my $filter= $exp ? " filter: $exp" : ''; warn "test $i: $id $filter - expected $expected_pos, actual $pos\n"; } } exit 0; __DATA__ #id exp expected doc _ 1 doc elt1 0 doc toto 0 elt1_1 _ 1 elt1_1 elt1 1 elt1_1 toto 0 elt1_2 _ 2 elt1_2 elt1 2 elt1_2 toto 0 elt2_1 _ 4 elt2_1 elt1 0 elt2_1 elt2 1 elt2_1 toto 0 elt2_2 _ 6 elt2_2 elt1 0 elt2_2 elt2 2 elt2_2 toto 0 XML-Twig-3.50/t/test_entities.t0000755000175000017500000001154712346001774016605 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; #use diagnostics; use XML::Twig; $|=1; my $TMAX=6; # do not forget to update! print "1..$TMAX\n"; my $doc= read_data(); # test 1 : roots and twig_print_outside_roots my $result_file= "test_entities.res1"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; my $t= XML::Twig->new( twig_roots => { elt2 => sub { $_->print} }, twig_print_outside_roots => 1, #load_DTD => 1, error_context => 2, ); select RESULT; $t->safe_parse( $doc) or die "This error is probably due to an incompatibility between XML::Twig and the version of libexpat that you are using\n See the README and the XML::Twig FAQ for more information\n";; close RESULT; select STDOUT; check_result( $result_file, 1); # test 2 : roots only, test during parsing $result_file= "test_entities.res2"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t= XML::Twig->new( twig_roots => { elt2 => sub { $_->print} }, error_context => 1, ); select RESULT; $t->parse( $doc); close RESULT; select STDOUT; check_result( $result_file, 2); # test 3 : roots only, test parse result $result_file= "test_entities.res3"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t= XML::Twig->new( twig_roots => { elt2 => 1 }, pretty_print => 'indented', error_context => 1, ); $t->parse( $doc); $t->print( \*RESULT); close RESULT; check_result( $result_file, 3); # test 4 : roots and twig_print_outside_roots $result_file= "test_entities.res4"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t= XML::Twig->new( twig_roots => { elt2 => sub { $_->print} }, twig_print_outside_roots => 1, keep_encoding => 1, error_context => 1, ); select RESULT; $t->parse( $doc); close RESULT; select STDOUT; check_result( $result_file, 4); # test 5 : roots only, test during parsing $result_file= "test_entities.res5"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t= XML::Twig->new( twig_roots => { elt2 => sub { $_->print} }, keep_encoding => 1, error_context => 1, ); select RESULT; $t->parse( $doc); close RESULT; select STDOUT; check_result( $result_file, 5); # test 6 : roots only, test parse result $result_file= "test_entities.res6"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t= XML::Twig->new( twig_roots => { elt2 => 1 }, pretty_print => 'indented', keep_encoding => 1, error_context => 1, ); $t->parse( $doc); $t->print( \*RESULT); close RESULT; check_result( $result_file, 6); exit 0; sub check_result { my( $result_file, $test_no)= @_; # now check result my $expected_result= read_data(); my $result= read_result( $result_file); if( $result eq $expected_result) { print "ok $test_no\n"; } else { print "not ok $test_no\n"; print STDERR "\ntest $test_no:\n", "expected: \n$expected_result\n", "real: \n$result\n"; } } sub read_data { local $/="\n\n"; my $data= ; $data=~ s{^\s*#.*\n}{}m; # get rid of comments $data=~ s{\s*$}{}s; # remove trailing spaces (and \n) $data=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines return $data; } sub read_result { my $file= shift; local $/="\n"; open( RESULT, "<$file") or die "cannot read $file: $!"; my @result= grep {m/\S/} ; my $result= join( '', @result); $result=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines close RESULT; unlink $file; return $result; } __DATA__ # doc 1 toto &ent1; tata &ent2; tutu &ent3; tutu &ent4; tutu &ent5; # expected_res 1 toto &ent1; tata &ent2; tutu &ent3; tutu &ent4; tutu &ent5; # expected_res 2 tata &ent2;tutu &ent4; # expected_res 3 tata &ent2; tutu &ent4; # expected_res 4 toto &ent1; tata &ent2; tutu &ent3; tutu &ent4; tutu &ent5; # expected_res 5 tata &ent2; tutu &ent4; # expected_res 6 tata &ent2; tutu &ent4; XML-Twig-3.50/t/test_xml_split_w_decl.xml0000644000175000017500000000057612346001774020643 0ustar mrodrigumrodrigu elt1 content 1 elt1 content 2 elt1 content 3 elt1 content 4 elt1 content 5 elt1 content 6 elt1 content 7 elt1 content 8 elt1 content 9 XML-Twig-3.50/t/test_simplify.t0000755000175000017500000000776412414174534016624 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; foreach my $module ( qw( XML::Simple Test::More Data::Dumper YAML) ) { if( eval "require $module") { import $module; } else { print "1..1\nok 1\n"; warn "skipping: $module is not installed\n"; exit; } } if( $XML::Simple::VERSION < 2.09) { print "1..1\nok 1\n"; warn "skipping: need XML::Simple 2.09 or above\n"; exit; } undef $XML::Simple::PREFERRED_PARSER; $XML::Simple::PREFERRED_PARSER= 'XML::Parser'; $/="\n\n"; my @doc= ; my @options= ( { }, { content_key => 'foo' }, { group_tags => { templates => 'template'} }, { group_tags => { dirs => 'dir', templates => 'template'} }, { forcearray => 1 }, { forcearray => [ qw(server) ] }, { noattr => 1, }, { noattr => 0, }, { content_key => 'mycontent' }, { content_key => '-mycontent' }, { var_attr => 'var' }, { var_attr => 'var', var_regexp => qr/\$\{?(\w+)\}?/ }, { variables => { var => 'foo' } }, { keyattr => [ qw(name)] }, { keyattr => [ 'name' ] }, { keyattr => [ qw(foo bar)] }, { keyattr => {server => 'name' } }, { keyattr => {server => '+name' } }, { keyattr => {server => '-name' } }, { normalize_space => 1 }, { normalise_space => 2 }, { group_tags => { f1_ar => 'f1' } }, { group_tags => { f1_ar => 'f1', f2_ar => 'f2'} }, ); plan( tests => @options * @doc); $SIG{__WARN__} = sub { }; foreach my $doc (@doc) { foreach my $options (@options) { (my $options_text= Dumper( $options))=~ s{\s*\n\s*}{ }g; $options_text=~ s{^\$VAR1 = }{}; my( $options_twig, $options_simple)= UNIVERSAL::isa( $options, 'ARRAY') ? @$options : ($options, $options); my $t = XML::Twig->new->parse( $doc); my $twig = $t->root->simplify( %$options_twig); my $doc_name = $t->root->att( 'doc'); delete $options_simple->{var_regexp}; my $simple = XMLin( $doc, %$options_simple); my $res=is_deeply( $twig, $simple, "doc: $doc_name - options: $options_text" ); #. Dump( {twig => $twig, simple => $simple})); #exit unless( $res); } } exit 0; __DATA__
10.0.0.101
10.0.1.101
10.0.0.102
10.0.0.103
10.0.1.103
localhost /home/mrodrigu/standards ${base}/tools foovar is ${var} text with spaces text with spaces text with spaces text with spaces f1 1f1 2 f2 1f2 2
something
0
XML-Twig-3.50/t/test_3_32.t0000755000175000017500000000153212346001775015421 0ustar mrodrigumrodrigu#!/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=1; print "1..$TMAX\n"; if( $] >= 5.008) { # test non ascii letters at the beginning of an element name in a selector # can't use non ascii chars in script, so the tag name needs to come from the doc! my $doc=q{étésummerestate}; my $t= XML::Twig->parse( $doc); my $tag= $t->root->first_child( 'tag')->text; foreach ($t->root->children( 'elt')) { $_->set_tag( $tag); } is( $t->root->first_child( $tag)->text, 'summer', 'non ascii letter to start a name in a condition'); } else { skip( 1, "known bug in perl $]: tags starting with a non ascii letter cannot be used in expressions"); } exit; 1; XML-Twig-3.50/t/test_new_features_3_22.html0000644000175000017500000000014012637027427020664 0ustar mrodrigumrodriguTt
t2

t3XML-Twig-3.50/t/xmlxpath_28ancestor2.t0000755000175000017500000000223612346001775017715 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//Footnote'); ok(@nodes, 1); my $footnote = $nodes[0]; #@nodes = $footnote->findnodes('ancestor::*', $t); @nodes = $footnote->findnodes( 'ancestor::*'); ok(@nodes, 3); @nodes = $footnote->findnodes('ancestor::text:footnote', $t); ok(@nodes, 1); exit 0; __DATA__ 2 AxKit is very flexible in how it lets you transform the XML on the server, and there are many modules you can plug in to AxKit to allow you to do these transformations. For this reason, the AxKit installation does not mandate any particular modules to use, instead it will simply suggest modules that might help when you install AxKit. XML-Twig-3.50/t/test3.t0000755000175000017500000000752512346001775014766 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; # This just tests a complete twig, no callbacks # additional tests for element creation/parse and # space policy # plus test for the is_pcdata method $|=1; use XML::Twig; my $i=0; my $failed=0; my $TMAX=23; # do not forget to update! print "1..$TMAX\n"; my $p1= XML::Twig::Elt->new( 'para', 'p1'); $p1->set_id( 'p1'); etest( $p1, 'para', 'p1', 'Element creation'); my $p2= XML::Twig::Elt->parse( 'para2'); etest( $p2, 'para', 'p2', 'Element parse'); my $s1= parse XML::Twig::Elt( '

title1para 3
'); etest( $s1, 'section', 's1', 'Element parse (complex)'); my $p3= $s1->first_child( 'para'); etest( $p3, 'para', 'p3', 'Element parse (sub-element)'); my $string= "\n

para

\n

\n
"; my $t1= new XML::Twig( DiscardSpacesIn => [ 'doc']); $t1->parse( $string); sttest( $t1->root, "

para

\n

", 'DiscardSpacesIn'); my $t2= new XML::Twig( DiscardSpacesIn => [ 'doc', 'p']); $t2->parse( $string); sttest( $t2->root, "

para

", 'DiscardSpacesIn'); my $t3= new XML::Twig( KeepSpaces =>1); $t3->parse( $string); sttest( $t3->root, $string, 'KeepSpaces'); my $t4= new XML::Twig( KeepSpacesIn =>[ 'p']); $t4->parse( $string); sttest( $t4->root, "

para

\n

", 'KeepSpacesIn'); my $p4= XML::Twig::Elt->parse( $string, KeepSpaces => 1); sttest( $p4, $string, 'KeepSpaces'); my $p5= XML::Twig::Elt->parse( $string, DiscardSpaces => 1); sttest( $p5, '

para

', "DiscardSpaces"); $p5= XML::Twig::Elt->parse( $string); sttest( $p5, '

para

', "DiscardSpaces (def)"); my $p6= XML::Twig::Elt->parse( $string, KeepSpacesIn => ['p']); sttest( $p6, "

para

\n

", "KeepSpacesIn 1"); my $p7= XML::Twig::Elt->parse( $string, KeepSpacesIn => [ 'doc', 'p']); sttest( $p7, "\n

para

\n

\n
", "KeepSpacesIn 2"); my $p8= XML::Twig::Elt->parse( $string, DiscardSpacesIn => ['doc']); sttest( $p8, "

para

\n

", "DiscardSpacesIn 1 "); my $p9= XML::Twig::Elt->parse( $string, DiscardSpacesIn => [ 'doc', 'p']); sttest( $p9, "

para

", "DiscardSpacesIn 2"); my $string2= "

para bold end of para

"; my $p10= XML::Twig::Elt->parse( $string2,); sttest( $p10, '

para bold end of para

', "mixed content"); my $string3= "\n

para

\n

\n

\n
"; my $p11= XML::Twig::Elt->parse( $string3, KeepSpaces => 1); sttest( $p4, $string, 'KeepSpaces'); my $p12= XML::Twig::Elt->parse( $string3, KeepSpacesIn => [ 'doc']); sttest( $p12, "\n

para

\n

\n
", 'KeepSpacesIn'); my $p13= XML::Twig::Elt->parse( $string3, KeepSpaces => 1); sttest( $p13, "\n

para

\n

\n

\n
", 'KeepSpaces'); my $p14= XML::Twig::Elt->parse( $string2); my $is_pcdata= $p14->is_pcdata; ok( $is_pcdata ? 0 : 1, "is_pcdata on a "); my $pcdata= $p14->first_child( PCDATA); $is_pcdata= $pcdata->is_pcdata; ok( $pcdata->is_pcdata, "is_pcdata on PCDATA"); my $erase_string='text 1 text 2 text 3 text 4'; my $er_t= new XML::Twig( TwigHandlers => { selt => sub { $_[1]->erase; } }); $er_t->parse( $erase_string); sttest( $er_t->root, 'text 1 text 2 text 3 text 4', "erase"); # test whether Twig packs strings my $br_pcdata= "line 1\nline 2\nline 3\n"; my $doc_br_pcdata= "$br_pcdata"; my $t_br_pcdata= new XML::Twig(); $t_br_pcdata->parse( $doc_br_pcdata); $pcdata= $t_br_pcdata->root->first_child->pcdata; stest( $pcdata, $br_pcdata, "multi-line pcdata"); exit 0; XML-Twig-3.50/t/test_bugs_3_19.t0000755000175000017500000001022512346001774016444 0ustar mrodrigumrodrigu#!/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=26; print "1..$TMAX\n"; { #bug with long CDATA # get an accented char in iso-8859-1 my $latin1_char= perl_io_layer_used() ? '' : slurp( File::Spec->catfile('t', "latin1_accented_char.iso-8859-1")); chomp $latin1_char; my %cdata=( "01- 1025 chars" => 'x' x 1025 . 'a', "02- short CDATA with nl" => "first line\nsecond line", "03- short CDATA with ]" => "first part]second part", "04- short CDATA with ] and spaces" => "first part ] second part", "05- 1024 chars with accent" => $latin1_char x 1023 . 'a', "06- 1025 chars with accent" => $latin1_char x 1024 . 'a', "07- 1023 chars, last a nl" => 'x' x 1022 . "\n", "08- 1023 chars, last a ]" => 'x' x 1022 . "]", "09- 1024 chars, last a nl" => 'x' x 1023 . "\n", "10- 1024 chars, last a ]" => 'x' x 1023 . "]", "11- 1025 chars, last a nl" => 'x' x 1024 . "\n", "12- 1025 chars, last a ]" => 'x' x 1024 . "]", "13- 1050 chars, last a nl" => ('1' x 1024) . ('2' x 25) . "\n", "14- 1050 chars, last a ]" => ('1' x 1024) . ('2' x 25) . "]", '15- 1060 chars, ] and \n' => ('1' x 1024) . ('2' x 26) . "\n \n ]\n]]\n", '16- 1060 chars, ] and \n' => ('1' x 1024) . ('2' x 26) . "\n \n ]\n]]", '17- 1060 chars, ] and \n' => ('1' x 1024) . ('2' x 26) . "\n \n ]\n]] ", '18- 1060 chars, ] and \n' => ('1' x 1024) . ('2' x 26) . "\n \n ]\n]] a", '19- 1060 chars, ] and \n' => '1' x 500 . "\n \n ]\n]] a" . '2' x 500 . "\n \n ]\n]] a", "20- 800 chars with accent" => $latin1_char x 800, "21- 800 chars with accent" => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$latin1_char" x 16, "22- 1600 chars with accent" => "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$latin1_char" x 32, '23- 1600 chars with accent and \n' => "aaaaaaaa]aaaaaaaaaaaaaaaaaaaaaaaaa\naaaaaaaaaaaaaaa$latin1_char" x 32, ); if( ($] == 5.008) || ($] < 5.006) ) { skip( scalar keys %cdata, "KNOWN BUG in 5.8.0 and 5.005 with keep_encoding and long (>1024 char) CDATA, " . "see http://rt.cpan.org/Ticket/Display.html?id=14008" ); } elsif( perl_io_layer_used()) { skip( scalar keys %cdata, "cannot test parseurl when UTF8 perIO layer used " . "(due to PERL_UNICODE or -C option used)\n" ); } else { foreach my $test (sort keys %cdata) { my $cdata=$cdata{$test}; my $doc= qq{}; my $twig= XML::Twig->new( keep_encoding => 1)->parse($doc); my $res = $twig->root->first_child->cdata; is( $res, $cdata, "long CDATA with keep_encoding $test"); } } } { # testing _dump my $doc= q{foobartototatatitiand now a long (more than 40 characters) text to see if it gets shortened by default (or not)}; my $t= XML::Twig->new->parse( $doc); my $dump= q{document |-doc | |-elt att="xyz" | |-- (cpi before) '' | | |-PCDATA: 'foo' | |-elt | | |-PCDATA: 'bar' | | |-CDATA: 'baz' | |-elt2 | |-- (cpi before) '' | | |-PCDATA: 'toto' | | |-b | | | |-PCDATA: 'tata' | | |-PCDATA: 'titi' | |-elt3 | |-elt | | |-PCDATA: 'and now a long (more than 40 characters) tex ... see if it gets shortened by default (or not)' }; is( $t->_dump( { extra => 1 }), $dump, "_dump with extra on"); (my $no_extra= $dump)=~ s{^.*cpi before.*\n}{}gm; is( $t->_dump( ), $no_extra, "_dump without extra"); (my $no_att= $no_extra)=~ s{ att=.*}{}g; is( $t->_dump( { atts => 0 }), $no_att, "_dump without atts"); } XML-Twig-3.50/t/xmlxpath_21allnodes.t0000755000175000017500000000245212346001775017607 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 13); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//GGG/ancestor::*'); ok(@nodes, 4); @nodes = $t->findnodes( '//GGG/descendant::*'); ok(@nodes, 3); @nodes = $t->findnodes( '//GGG/following::*'); ok(@nodes, 3); ok($nodes[0]->getName, "VVV"); ok($nodes[1]->getName, "CCC"); ok($nodes[2]->getName, "DDD"); @nodes = $t->findnodes( '//GGG/preceding::*'); ok(@nodes, 5); ok($nodes[0]->getName, "BBB"); # document order, not HHH @nodes = $t->findnodes( '//GGG/self::*'); ok(@nodes, 1); ok($nodes[0]->getName, "GGG"); @nodes = $t->findnodes( '//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*'); ok(@nodes, 16); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_16axisprec_sib.t0000755000175000017500000000160612346001774020464 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 7); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '/AAA/XXX/preceding-sibling::*'); ok(@nodes, 1); ok($nodes[0]->getName, "BBB"); @nodes = $t->findnodes( '//CCC/preceding-sibling::*'); ok(@nodes, 4); @nodes = $t->findnodes( '/AAA/CCC/preceding-sibling::*[1]'); ok($nodes[0]->getName, "XXX"); @nodes = $t->findnodes( '/AAA/CCC/preceding-sibling::*[2]'); ok($nodes[0]->getName, "BBB"); exit 0; __DATA__ XML-Twig-3.50/t/test_error_with_unicode_layer0000755000175000017500000000113012346001775021571 0ustar mrodrigumrodriguuse XML::Twig; use strict; use Config; my( $infile)= @ARGV; my $perl= used_perl(); open( FH, "$perl -p -e1 $infile |") or die $!; XML::Twig->nparse( \*FH); die "OK\n"; sub used_perl { my $perl; if( $^O eq 'VMS') { $perl= $Config{perlpath}; } # apparently $^X does not work on VMS else { $perl= $^X; } # but $Config{perlpath} does not work in 5.005 if ($^O ne 'VMS' && $Config{_exe} && $perl !~ m{$Config{_exe}$}i) { $perl .= $Config{_exe}; } $perl .= " -Iblib/lib"; if( $ENV{TEST_COVER}) { $perl .= " -MDevel::Cover"; } return $perl; } XML-Twig-3.50/t/test_new_features_3_15.t0000755000175000017500000000106312346001775020170 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; # 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 $indented="\n \n\n"; (my $straight=$indented)=~ s{\s}{}g; is( XML::Twig->new( pretty_print => 'indented')->parse( $indented)->sprint, $indented, "pretty printed doc"); exit; is( XML::Twig->new()->parse( $indented)->sprint, $straight, "non pretty printed doc"); } XML-Twig-3.50/t/xmlxpath_12axisdescendant.t0000755000175000017500000000115512346001774021001 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 6); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '/descendant::*'); ok(@nodes, 11); @nodes = $t->findnodes( '/AAA/BBB/descendant::*'); ok(@nodes, 4); @nodes = $t->findnodes( '//CCC/descendant::*'); ok(@nodes, 6); @nodes = $t->findnodes( '//CCC/descendant::DDD'); ok(@nodes, 3); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_03star.t0000755000175000017500000000105012346001774016747 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '/AAA/CCC/DDD/*'); ok(@nodes, 4); @nodes = $t->findnodes( '/*/*/*/BBB'); ok(@nodes, 5); @nodes = $t->findnodes( '//*'); ok(@nodes, 17); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_31vars.t0000755000175000017500000000755212346001775016770 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test::More; use XML::Twig::XPath; eval "use XML::XPathEngine"; if( $@) { print "1..1\nok 1\n"; warn "skipping, using variables in XPath requires XML::XPathEngine\n"; exit; } plan( tests => 8); my( $employees, $areas)= do { local $/="\n\n"; ; }; { # test all data in 1 single file my $data= "$employees$areas"; my $t = XML::Twig::XPath->new->parse( $data); { $t->set_var( salary => 12000); my @nodes= $t->findnodes('/data/employees/employee[@salary=$salary]/name'); is( results( @nodes), 'e3:e4', '1 doc, var is a litteral'); } { $t->set_var( E => $t->find( '/data/employees/employee[@salary>10000]')); $t->set_var( A => $t->find( '/data/areas/area[district="Brooklyn"]/street')); my @nodes = $t->findnodes('$E[work_area/street = $A]/name'); is( results( @nodes), 'e3:e4', '1 doc, var is a node set'); } { $t->set_var( org => 'A'); my @nodes= $t->findnodes('/data/employees/employee[@org=$org]/name'); is( results( @nodes), 'e5', '1 doc, var is a simple litteral'); } { $t->set_var( org => 'A/B'); my @nodes= $t->findnodes('/data/employees/employee[@org=$org]/name'); is( results( @nodes), 'e6', '1 doc, var is an XPath-like litteral'); } } { # test with data in 2 single file my $te = XML::Twig::XPath->new->parse( $employees); my $ta = XML::Twig::XPath->new->parse( $areas); { $te->set_var( salary => 12000); my @nodes= $te->findnodes('/employees/employee[@salary=$salary]/name'); is( results( @nodes), 'e3:e4', '2 docs, var is a litteral'); } SKIP: { skip "node sets in an XPath variable are not supported with perl < 5.12", 1 unless $] >= 5.012; $te->set_var( E => $te->find( '/employees/employee[@salary>10000]')); $te->set_var( A => $ta->find( '/areas/area[district="Brooklyn"]/street')); my @nodes = $te->findnodes('$E[work_area/street = $A]/name'); is( results( @nodes), 'e3:e4', '2 docs, var is a node set'); } { $te->set_var( org => 'A'); my @nodes= $te->findnodes('/employees/employee[@org=$org]/name'); is( results( @nodes), 'e5', '2 docs, var is a simple litteral'); } { $te->set_var( org => 'A/B'); my @nodes= $te->findnodes('/employees/employee[@org=$org]/name'); is( results( @nodes), 'e6', '2 docs, var is an XPath-like litteral'); } } sub results { return join ':', map { $_->id || 'XX' } @_; } __DATA__ Employee 1 Fifth Avenue Employee 2 Abbey Court Employee 3 Abbey Court Employee 4 Broad Street Abbey Court Employee 5 Broad Street Abbey Court Employee 6 Broad Street Abbey Court Brooklyn Abbey Court Aberdeen Street Adams Street Manhattan Fifth Avenue Broad Street XML-Twig-3.50/t/test_unique_xpath.t0000755000175000017500000000372112346001775017467 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; print "1..65\n"; my $t= XML::Twig->new->parse( \*DATA); foreach my $c ($t->descendants( 'c')) { is( $c->xpath, $c->text, "xpath"); is( $t->findvalue( $c->text), $c->text, "findvalue (>0)"); } foreach my $d ($t->descendants( 'd')) { is( $t->findvalue( $d->text), $d->text, "findvalue (<0)"); } foreach( 1..4) { is( $_, $t->root->first_child( "[$_]")->att( 'pos'), "first_child[$_]"); is( 5-$_, $t->root->first_child( "[-$_]")->att( 'pos'), "first_child[-$_]"); is( $_, $t->root->first_child( "b[$_]")->att( 'pos'), "first_child b[$_]"); is( 5-$_, $t->root->first_child( "b[-$_]")->att( 'pos'), "first_child b[-$_]"); } my $e= $t->get_xpath( '/a/b[-1]/e', 0); foreach( 1..4) { is( $_, $e->first_child( "f[$_]")->att( 'fpos'), "first_child f[$_]"); is( 5-$_, $e->first_child( "f[-$_]")->att( 'fpos'), "first_child f[-$_]"); is( $_, $e->first_child( "g[$_]")->att( 'gpos'), "first_child g[$_]"); is( 5-$_, $e->first_child( "g[-$_]")->att( 'gpos'), "first_child g[-$_]"); } foreach( 1..8) { is( $_, $e->first_child( "[$_]")->att( 'pos'), "first_child [$_]"); is( 9-$_, $e->first_child( "[-$_]")->att( 'pos'), "first_child [-$_]"); } exit 0; __DATA__ /a/b[1]/c[1] /a/b[1]/c[2] /a/b[-4]/d[-2] /a/b[-4]/d[-1] /a/b[2]/c[1] /a/b[-3]/d[-2] /a/b[-3]/d[-1] tata /a/b[2]/c[2] /a/b[3]/c titi /a/b[4]/c /a/b[4]/d[-1] tutu XML-Twig-3.50/t/xmlxpath_02descendant.t0000755000175000017500000000063212346001775020113 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 4); ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok($t); my @bbb = $t->findnodes('//BBB'); ok(@bbb, 5); my @subbbb = $t->findnodes('//DDD/BBB'); ok(@subbbb, 3); exit 0; __DATA__ XML-Twig-3.50/t/test2_1.exp0000644000175000017500000000236412346001775015527 0ustar mrodrigumrodrigu ]>
S1 I1S1 I2S1 TitleS1 P1S2 P2Note P1S1 para 3
S2 introS2 TitleS2 P1S2 P2S2 P3
Annex TitleAnnex P1Annex P2
XML-Twig-3.50/t/is_field.t0000755000175000017500000000270612346001774015475 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; my $i=1; my $TMAX=43; # do not forget to update! print "1..$TMAX\n"; print "ok $i\n"; # loading $i++; my $t= XML::Twig->new(); $t->parse( \*DATA); foreach my $elt ($t->descendants) { if( ($elt->tag eq 'field') && !$elt->is_field) { print "not ok $i "; warn $elt->id, " not recognized as field\n"; } elsif( ($elt->tag ne 'field') && $elt->is_field) { print "not ok $i "; my $elt_id= $elt->id || $elt->text; warn " $elt_id recognized as field\n"; } else { print "ok $i\n"; } $i++; } exit 0; __DATA__ field 1 text 1 text 2 text 3 field 2 text 4 text 5field field 3 field 4 field 5field 6 field 7 field 8 field 9 0 a field 10 XML-Twig-3.50/t/test_3_27.t0000755000175000017500000004326212346001774015432 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=82; print "1..$TMAX\n"; { # test reverse call mode my $doc=q{ }; my $res=''; my $t= XML::Twig->new( twig_handlers => { '_all_' => sub { $res.= $_->id } }, top_down_handlers => 1, ) ->parse( $doc); is( $res, 'da1b1b2c1b3e1a2b4b5c2b6', 'top_down_handlers _all_'); $res=''; $t= XML::Twig->new( twig_handlers => { 'b' => sub { $res.= $_->id } }, top_down_handlers => 1, ) ->parse( $doc); is( $res, 'b1b2b3b4b5b6', 'top_down_handlers b)'); $res=''; $t= XML::Twig->new( twig_handlers => { _default_ => sub { $res.= $_->id } }, top_down_handlers => 1, ) ->parse( $doc); is( $res, 'da1b1b2c1b3e1a2b4b5c2b6', 'top_down_handlers _default_)'); $res=''; $t= XML::Twig->new( twig_handlers => { a => sub { $res.= $_->id; }, b => sub { $res.= $_->id; }, c => sub { $res.= $_->id; }, e => sub { $res.= $_->id; }, }, top_down_handlers => 1, ) ->parse( $doc); is( $res, 'a1b1b2c1b3e1a2b4b5c2b6', 'top_down_handlers with purge)'); } { my $called=0; my $t= XML::Twig->new( twig_handlers => { 'doc[@a="="]' => sub { $called++; } }) -> parse( ''); is( $called, 1, 'handler on attribute with a value of "="'); } { # test error message for XPath query starting with a / on a node when the twig is not available my $sect; { my $t= XML::Twig->nparse( ''); $sect= $t->root->first_child( 'sect'); } $sect->cut; is( $sect->get_xpath( './elt', 0)->sprint, '', " XPath query ok"); eval { $sect->get_xpath( '/doc/elt'); }; matches( $@, qr/^cannot use an XPath query starting with a \/ on a node not attached to a whole twig/, "XPath query starting with a /") ; } { # test updating #att in start_tag_handlers my( $b, $e11, $e12)= '' x 3; my $t= XML::Twig->new( start_tag_handlers => { a => sub { $_->parent->set_att( '#a' => 1); }, }, twig_handlers => { 'e1[@#a]/b' => sub { $b .= $_->id || $_->tag }, 'e1[@#a]' => sub { $e11 .= $_->id || $_->tag }, 'e1[!@#a]' => sub { $e12 .= $_->id || $_->tag }, 'e1[@#a=1]/b' => sub { $b .= $_->id || $_->tag }, }, ) ->parse( q{}) ; is( $b , 'b1b1', 'trigger on e1[@#a]/b'); is( $e11, 'e1-1', 'trigger on e1[@#a]' ); is( $e12, 'e1-2', 'trigger on e1[!@#a]' ); } { # numerical tests in handlers my( $ngt, $nlt, $nge, $nle, $neq, $nne)= '' x 6; my( $agt, $alt, $age, $ale, $aeq, $ane)= '' x 6; my $t= XML::Twig->new( twig_handlers => { 'n[@a>2]' => sub { $ngt .= $_->id }, 'n[@a>=2]' => sub { $nge .= $_->id }, 'n[@a<2]' => sub { $nlt .= $_->id }, 'n[@a<=2]' => sub { $nle .= $_->id }, 'n[@a=2]' => sub { $neq .= $_->id }, 'n[@a!=2]' => sub { $nne .= $_->id }, 'a[@a>"b"]' => sub { $agt .= $_->id }, 'a[@a>="b"]' => sub { $age .= $_->id }, 'a[@a<"b"]' => sub { $alt .= $_->id }, 'a[@a<="b"]' => sub { $ale .= $_->id }, 'a[@a="b"]' => sub { $aeq .= $_->id }, 'a[@a!="b"]' => sub { $ane .= $_->id }, }, ) ->parse( q{
}); is( $ngt, 'n3', ' numerical test: >' ); is( $nge, 'n2n3', ' numerical test: >='); is( $nlt, 'n1n4', ' numerical test: <' ); is( $nle, 'n1n2n4', ' numerical test: <='); is( $neq, 'n2', ' numerical test: ='); is( $nne, 'n1n3n4', ' numerical test: !='); is( $agt, 'a3', ' string test: >' ); is( $age, 'a2a3', ' string test: >='); is( $alt, 'a1a4', ' string test: <' ); is( $ale, 'a1a2a4', ' string test: <='); is( $aeq, 'a2', ' string test: ='); is( $ane, 'a1a3a4', ' string test: !='); } { # test former_* methods my $t= XML::Twig->nparse( ''); my $e2= $t->elt_id( 'e2'); ok( ! defined( $e2->former_parent), "former_parent on uncut element" ); ok( ! defined( $e2->former_prev_sibling), "former_prev_sibling on uncut element"); ok( ! defined( $e2->former_next_sibling), "former_next_sibling on uncut element"); $e2->cut; is( $e2->former_parent->id, "d", "former_parent on cut element" ); is( $e2->former_prev_sibling->id, "e1", "former_prev_sibling on cut element"); is( $e2->former_next_sibling->id, "e3", "former_next_sibling on cut element"); $e2->paste( after => $e2->former_next_sibling); is( $e2->former_parent->id, "d", "former_parent on cut element (after paste)" ); is( $e2->former_prev_sibling->id, "e1", "former_prev_sibling on cut element (after paste)"); is( $e2->former_next_sibling->id, "e3", "former_next_sibling on cut element (after paste)"); } { # test merge my $t= XML::Twig->nparse( 'foobar'); my $e= $t->first_elt( 'e'); $e->merge( $e->next_sibling); is( $e->text, 'foobar', "merge"); } if( $] > 5.008) { # testing ignore on the current element my $calls; my $h= sub { $calls.= $_[1]->tag; }; my $t= XML::Twig->new( twig_handlers => { _all_ => sub { $calls.= $_[1]->tag; } }, start_tag_handlers => { b => sub { shift()->ignore } } ) ->parse( q{}) ; is( $calls, 'ga', 'ignore on an element'); is( $t->sprint, '', 'tree build with ignore on an element'); # testing ignore on a non-current element $calls=''; my $t2= XML::Twig->new( twig_handlers => { _all_ => sub { $calls.= $_[1]->tag; } }, start_tag_handlers => { d => sub { $_[1]->parent->ignore } } ) ->parse( q{}) ; is( $calls, 'cfcfa', 'ignore on a parent element'); is( $t2->sprint, '', 'tree build with ignore on the parent of an element'); $calls=''; my $t3= XML::Twig->new( twig_handlers => { _all_ => sub { $calls.= $_[1]->tag; } }, start_tag_handlers => { d => sub { $_[1]->parent( 'b')->ignore } } ) ->parse( q{}) ; is( $calls, 'cfcfha', 'ignore on a grand-parent element'); is( $t3->sprint, '', 'tree build with ignore on the grand parent of an element'); $calls=''; # ignore from a regular handler my $t4= XML::Twig->new( twig_handlers => { _default_ => sub { $calls.= $_[1]->tag; }, g => sub { $calls.= $_[1]->tag; $_[1]->parent( 'b')->ignore; }, } ) ->parse( q{}) ; is( $calls, 'cdgfcdgfha', 'ignore from a regular handler'); is( $t4->sprint, '', 'tree build with ignore on the parent of an element in a regular handler'); $calls=''; # ignore from a regular handler my $t5= XML::Twig->new( twig_handlers => { _default_ => sub { $calls.= $_[1]->tag; }, g => sub { $calls.= $_[1]->tag; $_[1]->parent( 'b')->ignore; }, } ) ->parse( q{}) ; is( $calls, 'xcdgfcdgfha', 'ignore from a regular handler (2)'); is( $t5->sprint, '', 'tree build with ignore from a regular handler (2)'); eval { my $t6= XML::Twig->new( twig_handlers => { c => sub { $_->prev_elt( 'f')->ignore } }) ->parse( ''); }; matches( $@, '^element to be ignored must be ancestor of current element', 'error ignore-ing an element (not ancestor)'); eval { my $t6= XML::Twig->new( twig_handlers => { f => sub { $_->first_child( 'c')->ignore } }) ->parse( ''); }; matches( $@, '^element to be ignored must be ancestor of current element', 'error ignore-ing an element ( descendant)'); } else { skip( 12, "not tested under perl < 5.8"); } { my $doc=''; (my $indented_doc= $doc)=~ s{()}{" " x $2 . $1}eg; $indented_doc=~ s{>}{>\n}g; $indented_doc=~ s{\s*}{}g; is( XML::Twig->nparse( $doc)->sprint, $doc, "nparse output"); is( XML::Twig->nparse_e( $doc)->sprint, $doc, "nparse_e output"); is( XML::Twig->nparse_pp( $doc)->sprint, $indented_doc, "nparse_pp output"); is( XML::Twig->nparse_ppe( $doc)->sprint, $indented_doc, "nparse_ppe output"); } if( _use( 'HTML::TreeBuilder', 4.00) ) { # first alternative is pre-3.23_1, second one with 3.23_1 (and beyond?) { my $doc=qq{

dummy

}; is_like( XML::Twig->nparse( $doc)->sprint, '

dummy

', 'invalid att'); is_like( XML::Twig->nparse_e( $doc)->sprint, '

dummy

', 'invalid att (nparse_e)'); } { my $doc=qq{

dummy

}; # used to trigger an error, now XML::Twig is fault tolerant to bad attributes #eval { XML::Twig->nparse_e( $doc); }; #ok( $@, "error in html (nparse_e mode 2, HTB < 3.23 or >= 4.00: $@)"); is_like( XML::Twig->nparse_e( $doc)->sprint, '

dummy

', 'wrong attributes, nparse_e mode 2, HTB < 3.23 or >= 4.00' ); } { my $doc=qq{

dummy

}; # used to trigger an error, now XML::Twig is fault tolerant to bad attributes #eval { XML::Twig->nparse_e( $doc); }; #ok( $@, "error in html (nparse_e mode 3, HTB < 3.23 or >= 4.00: $@)"); is_like( XML::Twig->nparse_e( $doc)->sprint, '

dummy

', 'wrong attributes, nparse_e mode 2, HTB < 3.23 or >= 4.00' ); } } else { skip( 4 => "need HTML::TreeBuilder > 4.00 to test error display with HTML data"); } { my $e= XML::Twig::Elt->new( 'e'); is( $e->tag_to_span->sprint, '', "tag_to_span"); is( $e->tag_to_span->sprint, '', "tag_to_span again "); is( $e->tag_to_div->sprint, '
', "tag_to_div"); is( $e->tag_to_div->sprint, '
', "tag_to_div again "); } # added coverage { my $doc= "\n"; my $t= XML::Twig->nparse( $doc); (my $expected= $doc)=~ s{foo}{bar}; $t->root->first_child( '#CDATA')->set_content( ' bar '); is( $t->root->sprint , $expected, 'set_content on a CDATA element'); } { my $doc= "



"; my $t= XML::Twig->nparse( pretty_print => 'none', $doc); (my $expected= $doc)=~ s{(

|)}{

}g; is( $t->root->sprint( { empty_tags => 'expand' } ) , $expected, 'sprint br with empty_tags expand'); ($expected= $doc)=~ s{(

|)}{
}g; is( $t->root->sprint( { empty_tags => 'html' } ) , $expected, 'sprint br with empty_tags html'); ($expected= $doc)=~ s{(

|)}{
}g; is( $t->root->sprint( { empty_tags => 'normal' } ) , $expected, 'sprint br with empty_tags normal'); } { my $doc= "

foo

bar

"; my $t= XML::Twig->nparse( pretty_print => 'none', $doc); is( $t->root->sprint( { pretty_print => 'indented' } ) , "\n

foo

\n

bar

\n
\n", 'sprint br with pretty_print indented'); is( $t->root->sprint( { pretty_print => 'none' } ) , $doc, 'sprint br with pretty_print none'); } { my $doc='&'; my $t= XML::Twig->new; $t->set_keep_encoding( 1); is( $t->parse( $doc)->sprint, $doc, 'set_keep_encoding(1)'); $t->set_keep_encoding( 0); is( $t->parse( $doc)->sprint, $doc, 'set_keep_encoding(1)'); } { my $doc=''; is( XML::Twig->nparse( quote => 'single', $doc)->sprint, q{}, 'quote option'); } { my $doc= qq{]>\n}; (my $expected= $doc)=~ s{ \[.*?\]}{}; my $t= XML::Twig->nparse( $doc); my $entity_list = $t->entity_list; foreach my $entity ($entity_list->list()) { $entity_list->delete($entity->name); } is( $t->sprint( Update_DTD => 1 ), $expected, 'parse entities with all chars in their name'); } { my $tmp= "tmp"; foreach my $doc ( qq{]>}, qq{}, qq{}, ) { foreach my $keep_encoding ( 0..1) { open( MYOUT, ">$tmp") or die "cannot open $tmp: $!"; my $t= XML::Twig->new( twig_roots=> { dummy => sub {} }, twig_print_outside_roots => \*MYOUT, keep_encoding => $keep_encoding, ) ->parse( $doc); close MYOUT; is_like( slurp( $tmp), $doc, "file with no DTD but entities (keep_encoding: $keep_encoding)"); unlink $tmp; } } } { my $doc=qq{foobarbaztoto tutu}; my $t= XML::Twig->parse( $doc); is( $t->elt_id( "e1")->text( 'no_recurse'), 'foobaz', "text_only"); is( $t->elt_id( "e2")->text_only, 'toto tata tutu', "text_only (cdata section)"); is( $t->elt_id( "e")->text_only, 'bar', "text_only (no embedded elt)"); } { my $doc=qq{tutu <&ent; notata}; my $t= XML::Twig->parse( $doc); is( $t->elt_id( "e1")->text(), 'tutu <&ent; notata', "text wih ent"); is( $t->elt_id( "e1")->text( 'no_recurse'), 'tutu <&ent; tata', "text no_recurse wih ent"); is( $t->elt_id( "e1")->xml_text( ), 'tutu <&ent; notata', "xml_text wih ent"); is( $t->elt_id( "e1")->xml_text( 'no_recurse'), 'tutu <&ent; tata', "xml_text no_recurse wih ent"); } if( $] > 5.008) { my $r; XML::Twig->parse( twig_handlers => { '/a/b//c' => sub { $r++; } }, q{foo} ); ok( $r, "handler condition with // and nested elts (/a//b/c)"); } else { skip( 1, "not tested under perl < 5.8"); } if( $] > 5.008) { my @r; XML::Twig->parse( twig_handlers => { 's[@#a="1"]' => sub { push @r, $_->id}, 's/e[@x="1"]' => sub { $_->parent->set_att( '#a' => 1); }, }, q{ }, ); is( join( ':', @r), 's2:s3', 'inner handler changing parent attribute value'); } else { skip( 1, "not tested under perl < 5.8"); } if( $] > 5.008) { my @r; XML::Twig->parse( twig_roots => { '/d/s[@a="1"]/e[@a="1"]' => => sub { push @r, $_->id}, }, q{ }, ); is( join( ':', @r), 'e3:e8', 'complex condition with twig_roots'); } else { skip( 1, "not tested under perl < 5.8"); } exit 0; # or you get a weird error under 5.6.2 XML-Twig-3.50/t/pod_coverage.t0000755000175000017500000000061512346001774016351 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; if( ! $ENV{TEST_AUTHOR} ) { print "1..1\nok 1\n"; warn "Author test. Set \$ENV{TEST_AUTHOR} to a true value to run.\n"; exit; } eval "use Test::Pod::Coverage 1.00 tests => 1"; if( $@) { print "1..1\nok 1\n"; warn "Test::Pod::Coverage 1.00 required for testing POD coverage"; exit; } pod_coverage_ok( "XML::Twig", { trustme => [ 'isa' ] }); XML-Twig-3.50/t/test_meta_json.t0000755000175000017500000000022312346001775016726 0ustar mrodrigumrodriguuse Test::More; eval "use Test::CPAN::Meta::JSON"; plan skip_all => "Test::CPAN::Meta::JSON required for testing META.json" if $@; meta_json_ok(); XML-Twig-3.50/t/xmlxpath_09string_length.t0000755000175000017500000000103212346001774020653 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//*[string-length(name()) = 3]'); ok(@nodes, 2); @nodes = $t->findnodes( '//*[string-length(name()) < 3]'); ok(@nodes, 2); @nodes = $t->findnodes( '//*[string-length(name()) > 3]'); ok(@nodes, 3); exit 0; __DATA__ XML-Twig-3.50/t/xmlxpath_08name.t0000755000175000017500000000105212346001774016725 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//*[name() = "BBB"]'); ok(@nodes, 5); @nodes = $t->findnodes( '//*[starts-with(name(), "B")]'); ok(@nodes, 7); @nodes = $t->findnodes( '//*[contains(name(), "C")]'); ok(@nodes, 3); exit 0; __DATA__ XML-Twig-3.50/t/test_mark.t0000755000175000017500000000462212346001774015707 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # test the mark method 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 @data= map { chomp; [split /\t+/] } ; my $TMAX= 2 * @data; print "1..$TMAX\n"; foreach my $test (@data) { my( $doc, $regexp, $elts, $hits, $result)= @$test; (my $quoted_elts= $elts)=~ s{(\w+)}{'$1'}g; my @elts= eval( "($quoted_elts)"); my $t= XML::Twig->new->parse( $doc); my $root= $t->root; my @hits= $root->mark( $regexp, @elts); is( $t->sprint, $result, "mark( /$regexp/, $quoted_elts) on $doc"); is( scalar @hits, $hits, 'nb hits'); } exit 0; # doc regexp elts hits result __DATA__ text X (X) s 1 text X text X X s 1 text text X s 0 text text (X) s 0 text text X X s 1 text text X (X) s 1 text X text X \s*X\s* s 1 text text X \s*(X)\s* s 1 textX text X (\s*X\s*) s 1 text X text X text X s 1 text text text X text (X) s 1 text X text text X text \s*X\s* s 1 texttext text X text \s*(X)\s* s 1 textXtext text X text (\s*X\s*) s 1 text X text text XX X s 2 text text XX (X) s 2 text XX text X X X s 2 text text X X (X) s 2 text X X text XX text X s 2 text text text XX text (X) s 2 text XX text text XY text Y text X ([XY]+) s 3 text XY text Y text X text X X s, {a => 1} 1 text text X (X) s, {a => 1, b => 2} 1 text X text X1Y2 text X0 Y0X3Y4 text X X(\d)Y(\d) s 4 text 12 text X0 Y034 text X XML-Twig-3.50/t/test_3_48.t0000755000175000017500000000037012346001775015427 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 1; use utf8; { XML::Twig::_disallow_use( 'Tie::IxHash'); my $t; eval { $t= XML::Twig->new( keep_atts_order => 0); }; ok( $t, 'keep_atts_order => 0'); } exit; XML-Twig-3.50/t/xmlxpath_09a_string_length.t0000755000175000017500000000127612346001775021166 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 5); use XML::Twig::XPath; my $doc_one = qq|para one|; my $t= XML::Twig::XPath->new( keep_spaces => 1); $t->parse( $doc_one); ok( $t); my $doc_one_chars = $t->find( 'string-length(/doc/text())'); ok($doc_one_chars == 0, 1); my $doc_two = qq| para one has bold text |; $t->parse( $doc_two); ok( $t); my $doc_two_chars = $t->find( 'string-length(/doc/text())'); ok($doc_two_chars == 3, 1); my $doc_two_para_chars = $t->find( 'string-length(/doc/para/text())'); ok($doc_two_para_chars == 13, 1); exit 0; XML-Twig-3.50/t/xmlxpath_26predicate.t0000755000175000017500000000074312346001775017754 0ustar mrodrigumrodrigu#!/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( '//a/b[2]'); ok(@bbb, 2); @bbb = $t->findnodes( '(//a/b)[2]'); ok(@bbb, 1); exit 0; __DATA__ some 1 value 1 some 2 value 2 XML-Twig-3.50/t/test_xml_split_entities.xml0000644000175000017500000000016312346001775021223 0ustar mrodrigumrodrigu text with < > & and ' & and ']]> XML-Twig-3.50/t/test_xpath_cond.t0000755000175000017500000000613112346001774017101 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; my $t= XML::Twig->new; $t->parse( ' elt 1 elt 2 elt 3 2 3 <:elt id=":elt">yep, that is a valid name '); my @data= grep { !/^##/ && m{\S} } ; my @exp; my %result; foreach( @data) { chomp; my ($exp, $id_list) = split /\s*=>\s*/ ; $id_list=~ s{\s+$}{}; $result{$exp}= $id_list; push @exp, $exp; } my $nb_tests= keys %result; print "1..$nb_tests\n"; my $i=1; foreach my $exp ( @exp) { my $expected_result= $result{$exp}; my @result= $t->get_xpath( $exp); my $result; if( @result) { $result= join ' ', map { $_->id || $_->gi } @result; } else { $result= 'none'; } if( $result eq $expected_result) { print "ok $i\n"; } else { print "not ok $i\n"; print STDERR "$exp: expected '$expected_result' - real '$result'\n"; } $i++; } exit 0; __DATA__ /elt => none /elt[@foo="bar"] => none /*[@foo="bar"] => none //*[@foo="bar"] => none /* => doc /*[@id="doc"] => doc //*[@id="doc"] => doc //elt => elt-1 elt-2 elt-3 //*/elt => elt-1 elt-2 elt-3 /doc/elt => elt-1 elt-2 /*/elt => elt-1 elt-2 /doc/elt[ last()] => elt-2 /doc/*[ last()] => :elt //elt[@id='elt-1'] => elt-1 //*[@id='elt-1'] => elt-1 //[@id='elt-1'] => elt-1 //elt[@id='elt-1' or @id='elt-2'] => elt-1 elt-2 //elt[@id='elt-1' and @id='elt-2'] => none //elt[@id='elt-1' and @id!='elt-2'] => elt-1 //elt[@id=~ /elt/] => elt-1 elt-2 elt-3 //[@id='elt-1' or @id='elt-2'] => elt-1 elt-2 //[@id='elt-1' and @id='elt-2'] => none //[@id='elt-1' and @id!='elt-2'] => elt-1 //[@id=~ /elt/] => elt-1 elt-2 elt2-1 elt-3 elt2-2 elt2-3 elt2-4 :elt //*[@id='elt-1' or @id='elt-2'] => elt-1 elt-2 //*[@id='elt-1' and @id='elt-2'] => none //*[@id='elt-1' and @id!='elt-2'] => elt-1 //*[@id=~ /elt/] => elt-1 elt-2 elt2-1 elt-3 elt2-2 elt2-3 elt2-4 :elt //elt2[@att_int > 2] => elt2-4 /doc/elt2[ last()]/* => elt2-3 elt2-4 //*[@id=~/elt2/] => elt2-1 elt2-2 elt2-3 elt2-4 /doc/*[@id=~/elt2/] => elt2-1 elt2-2 /doc//*[@id=~/elt2/] => elt2-1 elt2-2 elt2-3 elt2-4 //*[@id=~/elt2-[34]/] => elt2-3 elt2-4 //*[@id!~/^elt/] => doc :elt //[@id=~/elt2-[34]/] => elt2-3 elt2-4 //[@id!~/elt2-[34]/] => doc elt-1 elt-2 elt2-1 elt-3 elt2-2 :elt //elt2[@id=~/elt2-[34]/] => elt2-3 elt2-4 //*[@id!~/elt2-[34]/] => doc elt-1 elt-2 elt2-1 elt-3 elt2-2 :elt //:elt => :elt //elt[string()="elt 1"] => elt-1 //elt[string()=~/elt 1/] => elt-1 //elt[string()=~/^elt 1/] => elt-1 //*[string()="elt 1"] => elt-1 #PCDATA //*[string()=~/elt 1/] => doc elt-1 #PCDATA //*[string()=~/^elt 1/] => doc elt-1 #PCDATA //[string()="elt 1"] => elt-1 #PCDATA //[string()=~/elt 1/] => doc elt-1 #PCDATA //[string()=~/^elt 1/] => doc elt-1 #PCDATA //[string()="elt 2"] => elt-2 #PCDATA //[string()=~/elt 2/] => doc elt-2 #PCDATA //[string()=~/^elt 2/] => elt-2 #PCDATA XML-Twig-3.50/t/test_bugs_3_15.t0000755000175000017500000001231612346001774016443 0ustar mrodrigumrodrigu#!/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=17; print "1..$TMAX\n"; { # test bug outputing end tag with pretty_print => nsgmls on my $out= XML::Twig->new( pretty_print => 'nsgmls')->parse( "text")->sprint; ok( XML::Twig->new( error_context => 1)->safe_parse( $out), "end tag with nsgmls option" . ($@ || '') ); } { # test bug RT #8830: simplify dies on mixed content ok( XML::Twig->new->parse( "text1")->root->simplify, "simplify mixed content"); } { # testing to see if bug RT #7523 is still around my $t= XML::Twig->new->parse( ''); if( eval( '$t->iconv_convert( "utf8");')) { $t->set_output_encoding( 'utf8'); eval { $t->sprint;}; ok( !$@, 'checking bug RT 7523'); } else { if( $@=~ m{^Can't locate Text/Iconv.pm} || $@=~ m{^Text::Iconv not available} ) { skip( 1, "Text::Iconv not available"); } elsif( $@=~ m{^Unsupported (encoding|conversion): utf8}) { skip( 1, "your version of iconv does not support utf8"); } else { skip( 1, "odd error creating filter with iconv: $@"); } } } { # bug on comments my $doc= "\n \n foo\n\n"; my $t= XML::Twig->new( comments => 'keep', pretty_print => 'indented') ->parse( $doc); is( $t->sprint => $doc, "comment with comments => 'keep'"); } { # bug with disapearing entities in attributes my $text= '&ent3;'; my $doc= qq{]>$text}; XML::Twig::Elt::init_global_state(); my $regular=XML::Twig->new( pretty_print => 'none')->parse( $doc)->root->sprint; (my $expected= $text)=~ s{&(uuml|ent2);}{}g; # yes, entities in attributes just vanish! is( $regular => $expected, "entities in atts, no option"); XML::Twig::Elt::init_global_state(); my $with_keep=XML::Twig->new(keep_encoding => 1)->parse( $doc)->root->sprint; is( $with_keep => $text, "entities in atts with keep_encoding"); XML::Twig::Elt::init_global_state(); my $with_dneaia=XML::Twig->new(do_not_escape_amp_in_atts => 1)->parse( $doc)->root->sprint; if( $with_dneaia eq '&ent3;') { skip( 1, "option do_not_escape_amp_in_atts not available (it's only available in an old version of expat), no worries"); } else { is( $with_dneaia => $text, "entities in atts with do_not_escape_amp_in_atts"); } # checking that all goes back to normal XML::Twig::Elt::init_global_state(); $regular=XML::Twig->new()->parse( $doc)->root->sprint; is( $regular => $expected, "entities in atts, no option"); } # bug on xmlns in path expression trigger { my $matched=0; my $twig = XML::Twig->new( map_xmlns => { uri1 => 'aaa', }, twig_handlers => { '/aaa:doc/aaa:elt' => sub { $matched=1; } } ) ->parse( q{}); ok( $matched, "using name spaces in path expression trigger"); $matched=0; $twig = XML::Twig->new( map_xmlns => { uri1 => 'aaa', }, twig_handlers => { 'aaa:doc/aaa:elt' => sub { $matched=1; } } ) ->parse( q{}); ok( $matched, "using name spaces in partial path expression trigger"); } # bug where the leading spaces are discarded in an element like

foobar

{ # check that leading spaces after a \n are discarded my $doc= "

\n foo\n

"; my $expected= "

foo

"; my $result= XML::Twig->new->parse( $doc)->sprint; is( $result => $expected, 'leading spaces kept when not after a \n'); } { # check that leading spaces NOT after a \n are kept around my $doc= "

foobar

"; my $result= XML::Twig->new->parse( $doc)->sprint; is( $result => $doc, 'leading spaces kept when not after a \n'); } { my $t= XML::Twig->new->parse( " elt 1 elt 2 "); is( scalar $t->descendants( '#PCDATA'), 3, 'properly parsed pcdata'); } { my $t= XML::Twig->new->parse( "\n elt 1 \n elt 2 \n"); is( scalar $t->descendants( '#PCDATA'), 2, 'properly parsed pcdata'); } { # bug RT 8137 my $doc= q{}; (my $expected= $doc)=~ s{ }{ }; is( XML::Twig->new( keep_encoding => 1)->parse( $doc)->sprint, $expected, 'keep_encoding and 2 spaces between gi and attribute' ); } { # copy of an element with extra_data_before_end_tag my $doc= 'datamore'; my $expected= 'datamore'; # pi's are not being moved around anymore my $elt= XML::Twig->new( pi => 'keep')->parse( $doc)->root->copy; is( $elt->sprint, $expected, 'copy of an element with extra_data_before_end_tag'); } { # copy of an element with extra_data_before_end_tag my $doc= ''; my $elt= XML::Twig->new( pi => 'keep')->parse( $doc)->root->copy; is( $elt->sprint, $doc, 'copy of an element with extra_data_before_end_tag'); } XML-Twig-3.50/t/xmlxpath_10pipe.t0000755000175000017500000000105512346001774016736 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use FindBin qw($Bin); BEGIN { unshift @INC, $Bin; } use xmlxpath_tools; use Test; plan( tests => 6); use XML::Twig::XPath; ok(1); my $t= XML::Twig::XPath->new->parse( \*DATA); ok( $t); my @nodes; @nodes = $t->findnodes( '//CCC | //BBB'); ok(@nodes, 3); ok($nodes[0]->getName, "BBB"); # test document order @nodes = $t->findnodes( '/AAA/EEE | //BBB'); ok(@nodes, 2); @nodes = $t->findnodes( '/AAA/EEE | //DDD/CCC | /AAA | //BBB'); ok(@nodes, 4); exit 0; __DATA__ XML-Twig-3.50/t/test_new_features_3_18.t0000755000175000017500000001126112346001774020173 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; my $DEBUG=0; print "1..44\n"; { # test tag regexp handler my @res; my $doc=q{}; my $handlers= { qr/^foo_/ => sub { push @res, $_->tag; }, foo_f2 => sub { push @res, uc $_->tag; 0 }, }; my $expected= 'foo_f1:FOO_F2:foo_f1:foo_f3'; XML::Twig->new( twig_handlers => $handlers)->parse( $doc); my $res= join( ':', @res); is( $res, $expected, "tag regexp handlers"); } { # test tag regexp handler with i modifier my @res; my $doc=q{}; my $handlers= { qr/^foo_/i => sub { push @res, $_->tag; }, foo_f2 => sub { push @res, uc $_->tag; 0 }, }; my $expected= 'foo_f1:FOO_F2:foo_f1:foo_f3:FOO_f4'; XML::Twig->new( twig_handlers => $handlers)->parse( $doc); my $res= join( ':', @res); is( $res, $expected, "tag regexp handlers"); } { # test tag regexp handler with all modifier my @res; my $doc=q{}; my $handlers= { qr/^foo_/xism => sub { push @res, $_->tag; }, foo_f2 => sub { push @res, uc $_->tag; 0 }, }; my $expected= 'foo_f1:FOO_F2:foo_f1:foo_f3:FOO_f4'; XML::Twig->new( twig_handlers => $handlers)->parse( $doc); my $res= join( ':', @res); is( $res, $expected, "tag regexp handlers"); } { # testing last_descendant my $t= XML::Twig->new->parse( ' t_e_3 t_e_1 t_e_2t_n ' ); my %exp2id= ( '' => 't_n', 'n' => 'n1', '#ELT' => 'n1', 'e' => 'e2', 'e[@id="e1"]' => 'e1', 'e2' => undef, ); foreach my $exp (sort keys %exp2id) { my $expected= $exp2id{$exp}; is( result( $t->last_elt( $exp)), $expected, "last_elt( $exp)"); is( result( $t->root->last_descendant( $exp)), $expected, "last_descendant( $exp)"); } # some more tests to check that we stay in te subtree and that we get the last descendant if it is itself is( result( $t->last_elt( 'e3')), 'e3', 'last_elt( e3)'); is( result( $t->root->last_descendant( 'e3')), 'e3', 'last_descendant( e3)'); is( result( $t->root->first_child( 'e3')->last_descendant( 'e3')), 'e3', 'last_descendant( e3) (on e3)'); is( result( $t->root->first_child( 'e3')->last_descendant()), 't_e_3', 'last_descendant() (on e3)'); is_undef( $t->root->last_child->last_descendant( 'e3'), 'last_descendant (no result)'); is( result( $t->root->first_child( 'e4')->last_descendant( 'e4')), 'e4', 'last_descendant( e4) (on e4)'); is( result( $t->root->first_child( 'e4')->last_descendant( )), 'e4', 'last_descendant( ) (on e4)'); sub result { my( $elt)= @_; return undef unless $elt; return $elt->id || $elt->text; } } {# testing trim my $expected; while( ) { chomp; next unless( m{\S}); if( s{^#}{}) { $expected= $_; } is( XML::Twig->new->parse( $_)->trim->root->sprint, $expected, "trimming '$_'"); } } { # testing children_trimmed_text my $t = XML::Twig->new; $t->parse(" hell foo o, \n world"); is( join( ':', $t->root->children_trimmed_text("e")), "hell:o, world" , "children_trimmed_text (list context)"); my $scalar= $t->root->children_trimmed_text("e"); is( $scalar, "hello, world" , "children_trimmed_text (scalar context)"); is( join( ':', $t->root->children_text("e")), " hell : o, \n world" , "children_text (list context)"); $scalar= $t->root->children_text("e"); is( $scalar, " hell o, \n world" , "children_text (scalar context)"); } __DATA__ #text1 text2 text1 text2 text1 text2 text1 text2 text1 text2 text1 text2 text1 text2 text1 text2 text1 text2 #text1 text2 text3 text1 text2 text3 #text1 text2 text3 text1 text2 text3 # #text hah! yep text hah! yep XML-Twig-3.50/t/test_3_35.t0000755000175000017500000000463712346001774015434 0ustar mrodrigumrodrigu#!/usr/bin/perl -w 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=10; print "1..$TMAX\n"; # escape_gt option { is( XML::Twig->parse( '')->root->insert_new_elt( '#COMMENT' => '- -- -')->twig->sprint, '', 'comment escaping'); } { my $t= XML::Twig->parse( 'foobarbazfoobarbaz2foobar2'); $t->root->cut_descendants( 'e[@a="c"]'); is( $t->sprint, 'bazfoobarbaz2', 'cut_descendants'); } { my $t=XML::Twig->new( pretty_print => 'none')->parse( ''); is( $t->root->_pretty_print, 0, '_pretty_print'); $t->set_pretty_print( 'indented'); is( $t->root->_pretty_print, 3, '_pretty_print'); } # additional tests to increase coverage { is( XML::Twig->parse( no_expand => 1, q{]>&foo;})->root->sprint, "&foo;\n", 'external entities with no_expand'); } { my $doc= q{fi4}; open( my $fh, '>', 'tmp_file'); my $t= XML::Twig->new( twig_handlers => { e => sub { $_->flush( $fh); }, g => sub { is( $_[0]->elt_id( 'i4')->text, 'fi4', 'elt_id, id exists'); nok( $_[0]->elt_id( 'i3'), 'elt_id, id flushed'); }, } ) ->parse( $doc); } { my $xpath=''; XML::Twig->parse( map_xmlns => { "http://foo.com" => 'bar' }, twig_handlers => { "bar:e" => sub { $xpath= $_[0]->path( $_->gi);}, }, q{} ); is( $xpath, '/bar:d/bar:e'); XML::Twig->parse( map_xmlns => { "http://foo.com" => 'bar' }, twig_handlers => { "bar:e" => sub { $xpath= $_[0]->path( $_->local_name);}, }, q{} ); is( $xpath, '/bar:d/bar:e'); } { my $t=XML::Twig->parse( pretty_print => 'none', ''); $t->first_elt( 'e3')->replace( $t->first_elt( 'e1')); is( $t->sprint, '', 'replace called on an element that has not been cut yet'); } 1; XML-Twig-3.50/t/test_autoencoding_conversion.t0000755000175000017500000000223712346001775021702 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # use strict; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; print "1..2\n"; if( $] < 5.008) { skip( 2, "needs perl 5.8 or above to test auto conversion"); } elsif( $ENV{PERL_UNICODE} && $ENV{PERL_UNICODE}=~ m{SA}) { skip( 2, 'auto conversion does not happen when $PERL_UNICODE set to SA'); } else { _use( 'Encode'); my $char_utf8 = qq{\x{e9}}; my $char_latin1 = encode("iso-8859-1", $char_utf8); my $doc_utf8 = qq{$char_utf8}; my $doc_latin1 = qq{$char_latin1}; my $file_utf8 = "doc_utf8.xml"; spit( $file_utf8, $doc_utf8); my $file_latin1 = "doc_latin1.xml"; spit( $file_latin1, $doc_latin1); my( $q, $q2) = ( ($^O eq "MSWin32") || ($^O eq 'VMS') ) ? ('"', "'") : ("'", '"'); my $lib= File::Spec->catfile( 'blib', 'lib'); my $run_it=qq{$^X -I $lib -MXML::Twig -e$q print XML::Twig->parse( $q2$file_latin1$q2)->root->text$q}; my $parsed= `$run_it`; is( $parsed, $char_utf8, 'testing auto transcoding of latin1 output'); is( $parsed, $char_latin1, 'testing auto transcoding of latin1 output'); } XML-Twig-3.50/t/test_comment_handler.t0000755000175000017500000000357212346001774020117 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Carp; # test for the various conditions in navigation methods use XML::Twig; if( $] < 5.008) { warn "skipped, not tested under perl < 5.8\n"; print "1..1\nok 1\n"; exit 0; } my $nb_tests=4; print "1..$nb_tests\n"; { my $result; my $t= XML::Twig->new( comments => 'process', twig_handlers => { '#COMMENT' => sub { $result .=$_->text; } }, ); $t->parse( q{}); my $expected= ' comment in doc '; if( $result eq $expected) { print "ok 1\n"; } else { print "not ok 1\n"; warn "expected: $expected\nfound : $result\n"; } } { my $result=''; my $t= XML::Twig->new( comments => 'process', twig_handlers => { '#COMMENT' => sub { $result .=$_->text; } }, ); $t->parse( q{}); my $expected= ' comment in doc '; if( $result eq $expected) { print "ok 2\n"; } else { print "not ok 2\n"; warn "expected: $expected\nfound : $result\n"; } } { my $result=''; my $t= XML::Twig->new( twig_handlers => { 'doc' => sub { $result= $_->{extra_data}; } },); $t->parse( q{}); my $expected= ''; if( $result eq $expected) { print "ok 3\n"; } else { print "not ok 3\n"; warn "expected: $expected\nfound : $result\n"; } } { my $result=''; my $t= XML::Twig->new( comments => 'process', twig_roots => { '/#COMMENT' => sub { $result= $_->{extra_data}; }, elt => sub { }, }); $t->parse( q{}); my $expected= ''; # This is a bug! if( $result eq $expected) { print "ok 4\n"; } else { print "not ok 4\n"; warn "expected: $expected\nfound : $result\n"; } } exit 0; XML-Twig-3.50/t/test_twig_roots.t0000755000175000017500000001725412346001774017162 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; #use diagnostics; use XML::Twig; $|=1; my $TMAX=12; # do not forget to update! print "1..$TMAX\n"; $/= "\n\n"; my $t= XML::Twig->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 1); $t= XML::Twig->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 2); $t= XML::Twig->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 3); $t= XML::Twig->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 4); $t= XML::Twig->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 5); $t= XML::Twig->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 6); $t= XML::Twig->new( twig_roots => { }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 7); $t= XML::Twig->new( twig_roots => { elt2 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 8); $t= XML::Twig->new( twig_roots => { elt3 => sub { } }, twig_print_outside_roots => \*RESULT, error_context => 1, ); test_twig( $t, 9); $t= XML::Twig->new( twig_roots => { elt => sub { print RESULT "elt handler called on ", $_->gi, "\n"; }, }, start_tag_handlers => { doc => sub { print RESULT "start tag handler called on ", $_->gi, "\n"; }, }, end_tag_handlers => { doc => sub { print RESULT "end tag handler called on $_[1]\n"; }, }, ); test_twig( $t, 10); # test with doc root as root $t= XML::Twig->new( twig_roots => { doc => sub { $_->print( \*RESULT); } }); test_twig( $t, 11); # test with elt as root $t= XML::Twig->new( twig_roots => { elt => sub { $_->print( \*RESULT); } }); test_twig( $t, 12); exit 0; sub test_twig { my( $t, $test_nb)= @_; my $doc= read_doc(); my $expected_result= read_expected_result(); my $result_file= "test_twig_roots.res1"; open( RESULT, ">$result_file") or die "cannot create $result_file: $!"; $t->parse( $doc); check_result( $result_file, $test_nb, $expected_result); close RESULT; } sub check_result { my( $result_file, $test_no, $expected_result)= @_; # now check result my $result= read_result( $result_file); if( $result eq $expected_result) { print "ok $test_no\n"; } else { print "not ok $test_no\n"; print STDERR "\ntest $test_no:\n", "expected: \n$expected_result\n", "real: \n$result\n"; } } { my $last_doc; my $buffered_result; sub read_doc { local $/="\n\n"; my $doc= ; # if the data starts with #doc then it's a doc, otherwise use the previous one if( $doc=~ /^\s*#\s*doc/) { $doc= clean_data( $doc); $last_doc= $doc; $buffered_result=''; return $doc; } else { $buffered_result= clean_data( $doc); return $last_doc; } } sub read_expected_result { if( $buffered_result) { return $buffered_result; } else { local $/="\n\n"; my $expected_result= ; $expected_result= clean_data( $expected_result); return $expected_result; } } } sub clean_data { my $data= shift; $data=~ s{^\s*#.*\n}{}m; # get rid of comments $data=~ s{\s*$}{}s; # remove trailing spaces (and \n) $data=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines return $data; } sub read_result { my $file= shift; local $/="\n"; open( RESULT, "<$file") or die "cannot read $file: $!"; my @result= grep {m/\S/} ; my $result= join( '', @result); $result=~ s{(^|\n)\s*(\n|$)}{}g; # remove empty lines close RESULT; unlink $file; return $result; } __DATA__ # doc 1 text subelt text another elt text an other type of element text of subelt # expected_res 1 text subelt text another elt text an other type of element text of subelt # expected_res 2 text subelt text another elt text text of subelt # expected_res 3 text subelt text another elt text an other type of element # doc 2 text subelt text another elt text an other type of element text of subelt # expected_res 4 text subelt text another elt text an other type of element text of subelt # expected_res 5 text subelt text another elt text text of subelt # expected_res 6 text subelt text another elt text an other type of element # doc 3 text subelt text another elt text an other type of element text of subelt # expected_res 7 text subelt text another elt text an other type of element text of subelt # expected_res 8 text subelt text another elt text text of subelt # expected_res 9 text subelt text another elt text an other type of element # doc 4 # expected_res 10 start tag handler called on doc elt handler called on elt end tag handler called on doc # expected_res 11 # expected_res 12 XML-Twig-3.50/t/test_class_methods.t0000755000175000017500000000416712346001774017611 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # testing methods on class attribute: # class set_class add_to_class att_to_class add_att_to_class move_att_to_class # tag_to_class add_tag_to_class set_tag_class in_class use strict; use Carp; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,"t"); use tools; use XML::Twig; my $DEBUG=0; my $TMAX=26; print "1..$TMAX\n"; { my $root= XML::Twig->new->parse( q{})->root; nok( $root->class, "no class"); $root->set_class( 'foo'); is( $root->class, 'foo', 'set_class'); $root->set_class( 'bar'); is( $root->class, 'bar', 'set_class'); ok( $root->in_class( 'bar'), 'in_class (ok)'); nok( $root->in_class( 'foo'), 'in_class (nok)'); $root->add_to_class( 'foo'); ok( $root->in_class( 'bar'), 'in_class (ok)'); ok( $root->in_class( 'foo'), 'in_class (ok)'); nok( $root->in_class( 'baz'), 'in_class (nok)'); $root->tag_to_class; is( $root->class, 'doc', 'tag_to__class'); ok( $root->in_class( 'doc'), 'in_class (ok)'); nok( $root->in_class( 'foo'), 'in_class (nok)'); $root->tag_to_class; is( $root->class, 'doc', 'tag_to_class (with existing class)'); $root->add_tag_to_class; is( $root->class, 'doc', 'add_tag_to_class'); $root->att_to_class( 'att1'); is( $root->class, 'val1', 'att_to_class'); $root->att_to_class( 'att1'); is( $root->class, 'val1', 'att_to_class (with existing class)'); $root->add_att_to_class( 'att'); is( $root->class, 'val1', 'att_to_class (non existing att)'); $root->add_att_to_class( 'att2'); is( $root->class, 'val1 val2', 'att_to_class (2 classes now)'); ok( $root->in_class( 'val1'), 'in_class'); ok( $root->in_class( 'val2'), 'in_class'); nok( $root->in_class( 'val'), 'in_class (nok)'); $root->set_tag_class( 'new'); is( $root->sprint, '', 'set_tag_class'); $root->move_att_to_class( 'att2'); is( $root->sprint, '', 'set_tag_class'); ok( $root->matches( '.doc'), 'match on class (first)'); ok( $root->matches( '.val1'), 'match on class (middle)'); ok( $root->matches( '.val2'), 'match on class (last)'); nok( $root->matches( '.val'), 'match on class (not good)'); } exit 0; XML-Twig-3.50/t/test_class_selector.t0000755000175000017500000000314512346001775017762 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use File::Spec; use lib File::Spec->catdir(File::Spec->curdir,'t'); use tools; my @DATA; while( ) { chomp; my( $cond, $expected)= split /\s*=>\s*/; push @DATA, [$cond, $expected]; } my $TMAX= 20; print "1..$TMAX\n"; my $doc=q{e1e2e3}; my $doc_dot=q{wrong e1wrong e2wrong e3e1e2e3}; my $t= XML::Twig->parse( $doc); foreach my $test (@DATA) { my( $cond, $expected)= @$test; my $got= join '', map { $_->text } $t->root->children( $cond); is( $got, $expected, "navigation: $cond" ); } if( $] > 5.008) { foreach my $test (@DATA) { my( $cond, $expected)= @$test; my $got=''; XML::Twig->new( twig_handlers => { $cond => sub { $got.= $_->text } }, css_sel => 1, ) ->parse( $doc); is( $got, $expected, "handlers (css_sel enabled): $cond" ); } foreach my $test (@DATA) { my( $cond, $expected)= @$test; next if $cond !~ m{^e}; my $got=''; XML::Twig->new( twig_handlers => { $cond => sub { $got.= $_->text } },) ->parse( $doc_dot); is( $got, $expected, "handlers (css_sel NOT enabled): $cond" ); } } else { skip( 12, 'not tested under perl < 5.8'); } __DATA__ e.c1 => e1e2 e.c1[@a="v1"] => e2 e.c1[@a] => e2 e.c1[@a="v2"] => *.c1[@a="v1"] => e2 *.c1[@a="v2" or @a="v1"] => e2 .c1[@a="v1"] => e2 .c1[@a="v2" or @a="v1"] => e2 XML-Twig-3.50/t/test_cdata.t0000755000175000017500000000344312346001775016032 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use XML::Twig; $|=1; $/= "\n\n"; my $xml= ; print "1..4\n"; my( $t, $result, $expected_result); $t= XML::Twig->new( twig_handlers => { 'ehtml/#CDATA' => sub { $_->set_asis; } }); $t->parse( $xml); $result= $t->sprint; ($expected_result=)=~ s{\n*$}{}s; if( $result eq $expected_result) { print "ok 1\n"; } else { print "not ok 1\n"; warn "expected: $expected_result\n result : $result"; } $t= XML::Twig->new( twig_handlers => { 'ehtml/#CDATA' => sub { $_->remove_cdata; } }); $t->parse( $xml); $result= $t->sprint; ($expected_result=)=~ s{\n*$}{}s; if( $result eq $expected_result) { print "ok 2\n"; } else { print "not ok 2\n"; warn "expected: $expected_result\n result : $result"; } $t= XML::Twig->new( keep_encoding => 1, twig_handlers => { 'ehtml/#CDATA' => sub { $_->set_asis; } }); $t->parse( $xml); $result= $t->sprint; ($expected_result=)=~ s{\n*$}{}s; if( $result eq $expected_result) { print "ok 3\n"; } else { print "not ok 3\n"; warn "test keep_encoding / asis\n expected: $expected_result\n result : $result"; } $t= XML::Twig->new( keep_encoding => 1, twig_handlers => { 'ehtml/#CDATA' => sub { $_->remove_cdata; } }); $t->parse( $xml); $result= $t->sprint; ($expected_result=)=~ s{\n*$}{}s; if( $result eq $expected_result) { print "ok 4\n"; } else { print "not ok 4\n"; warn "test keep_encoding / remove_cdata\n expected: $expected_result\n result : $result"; } exit 0; __DATA__ text world & all]]> texthello
world & all
texthello<br>world & all texthello
world & all
texthello<br>world & all XML-Twig-3.50/t/test_3_45.t0000755000175000017500000000702312346001775015426 0ustar mrodrigumrodrigu#!/usr/bin/perl use strict; use warnings; use XML::Twig; use Test::More tests => 16; is( XML::Twig->new( keep_encoding => 1)->parse( q{})->sprint, q{}, "quote in att with keep_encoding"); # test CDATA sections in HTML escaping https://rt.cpan.org/Ticket/Display.html?id=86773 my $html = <<'EOF';
body
EOF # module => XML::Twig->new options my %html_conv= ( 'HTML::TreeBuilder' => {}, 'HTML::Tidy' => { use_tidy => 1 }, ); foreach my $module ( sort keys %html_conv) { SKIP: { eval "use $module"; skip "$module not available", 3 if $@ ; my $parser= XML::Twig->new( %{$html_conv{$module}}); my $xml = $parser->safe_parse_html($html); print $@ if $@; my @cdata = $xml->get_xpath('//#CDATA'); ok(@cdata == 1, "1 CDATA section found (using $module)"); ok(((index $xml->sprint, "//]]>") >= 0), "end of cdata ok in doc (using $module)"); #diag "\n", $xml->sprint, "\n"; my @elts = $xml->get_xpath('//script'); foreach my $el (@elts) { #diag $el->sprint; ok(((index $el->sprint, "//]]>") >= 0), "end of cdata ok in script element (using $module)"); } } } # test & in HTML (RT #86633) my $html_with_amp='

Marco&company

'; my $expected_body= '

Marco&company

'; SKIP: { eval "use HTML::Tidy"; skip "HTML::Tidy not available", 1 if $@ ; my $parsert = XML::Twig->new(); my $html_tidy = $parsert->safe_parse_html( { use_tidy => 1 }, "

Marco&company

"); diag $@ if $@; is( $html_tidy->first_elt( 'body')->sprint, $expected_body, "& in text, converting html with use_tidy"); } SKIP: { eval "use HTML::TreeBuilder"; skip "HTML::TreeBuilder not available", 1 if $@ ; my $parserh= XML::Twig->new(); my $html = $parserh->safe_parse_html("

Marco&company

"); diag $@ if $@; is( $html->first_elt( 'body')->sprint , $expected_body, "& in text, converting html with treebuilder"); } is( XML::Twig::_unescape_cdata( '<tag att="foo&bar&baz">>></tag>'), '>>', '_unescape_cdata'); SKIP: { skip "safe_print_to_file method does not work on Windows", 6 if $^O =~ m{win}i; # testing safe_print_to_file my $tmp= "safe_print_to_file.xml"; my $doc= "foo"; unlink( $tmp); # no check, it could not be there my $t1= XML::Twig->nparse( $doc)->safe_print_to_file( $tmp); ok( -f $tmp, "safe_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( 'foobar')->first_elt( 'b')->safe_print_to_file( $tmp); ok( -f $tmp, "safe_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); }; like( $@, qr/Couldn't open $tmp:/, 'parse a non-existent file'); my $non_existent="safe_non_existent_I_hope_01/tmp"; while( -f $non_existent) { $non_existent++; } # most likely unnecessary ;--) eval { $t1->safe_print_to_file( $non_existent); }; like( $@, qr/(does not exist|is not a directory)/, 'safe_print_to_file in non-existent dir'); } exit; XML-Twig-3.50/t/test_with_lwp.t0000755000175000017500000000470412346001775016614 0ustar mrodrigumrodrigu#!/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; eval { require LWP; }; if( $@) { import LWP; print "1..1\nok 1\n"; warn "skipping, LWP not available\n"; exit } # skip on Win32, it looks like we have a problem there (named pipes?) if( ($^O eq "MSWin32") && ($]<5.008) ) { print "1..1\nok 1\n"; warn "skipping, *parseurl methods not available on Windows with perl < 5.8.0\n"; exit } if( perl_io_layer_used()) { print "1..1\nok 1\n"; warn "cannot test parseurl when UTF8 perIO layer used (due to PERL_UNICODE or -C option used)\n"; exit; } my $TMAX=13; chdir 't'; print "1..$TMAX\n"; { my $t= XML::Twig->new->parseurl( 'file:test_with_lwp.xml', LWP::UserAgent->new); is( $t->sprint, 'text', "parseurl"); } { my $t= XML::Twig->new->parseurl( 'file:test_with_lwp.xml'); is( $t->sprint, 'text', "parseurl"); } { my $t= XML::Twig->new->safe_parseurl( 'file:test_with_lwp.xml'); is( $t->sprint, 'text', "parseurl"); } { warn "\n\n### warning is normal here ###\n\n"; my $t=0; if ($^O ne 'VMS') { # On VMS we get '%SYSTEM-F-ABORT, abort' and an exit when a file does not exist # Behaviour is probably different on VMS due to it not having 'fork' to do the # LWP::UserAgent request and (safe) parse of that request not happening in a child process. $t = XML::Twig->new->safe_parseurl( 'file:test_with_lwp_no_file.xml'); ok( !$t, "no file"); matches( $@, '^\s*(no element found|Ran out of memory for input buffer)', "no file, error message"); } else { skip( 2 => "running on VMS, cannot test error message for non-existing file"); } } { my $t= XML::Twig->new->safe_parseurl( 'file:test_with_lwp_not_wf.xml'); ok( !$t, "not well-formed"); matches( $@, '^\s*mismatched tag', "not well-formed, error message"); } { my $t= XML::Twig->new->parsefile( 'test_with_lwp.xml'); is( $t->sprint, 'text', "parseurl"); } { my $t= XML::Twig->new->safe_parsefile( 'test_with_lwp.xml'); is( $t->sprint, 'text', "parseurl"); } { my $t= XML::Twig->new->safe_parsefile( 'test_with_lwp_no_file.xml'); ok( !$t, "no file"); matches( $@, '^\s*Couldn', "no file, error message"); } { my $t= XML::Twig->new->safe_parsefile( 'test_with_lwp_not_wf.xml'); ok( !$t, "not well-formed"); matches( $@, '^\s*mismatched tag', "not well-formed, error message"); } exit 0; XML-Twig-3.50/META.yml0000664000175000017500000000113312637027512014531 0ustar mrodrigumrodrigu--- abstract: 'XML, The Perl Way' author: - 'Michel Rodriguez ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: XML-Twig no_index: directory: - t - inc requires: XML::Parser: '2.23' resources: repository: http://github.com/mirod/xmltwig version: '3.50' x_serialization_backend: 'CPAN::Meta::YAML version 0.012' XML-Twig-3.50/filter_for_5.0050000644000175000017500000000032012346001761016053 0ustar mrodrigumrodrigu# $Id: /xmltwig/trunk/filter_for_5.005 4 2007-03-16T12:16:25.259192Z mrodrigu $ if( $] < 5.006) { s{^(\s*)no warnings;}{$1# no warnings;}; } else { s{^(\s*)# no warnings; }{$1no warnings;}; } XML-Twig-3.50/tools/0000755000175000017500000000000012637027512014420 5ustar mrodrigumrodriguXML-Twig-3.50/tools/xml_grep/0000755000175000017500000000000012637027512016235 5ustar mrodrigumrodriguXML-Twig-3.50/tools/xml_grep/xml_grep0000755000175000017500000003252112346001777020005 0ustar mrodrigumrodrigu#!/usr/bin/perl -w use strict; use Getopt::Long; use Pod::Usage; use XML::Twig; my $VERSION="0.9"; # options (all used globally in the script) my( $help, $man, @roots, @paths, $files, $count, $nb_results, $nb_results_per_file, $encoding, @exclude, $wrap, $nowrap, $descr, $group, $pretty_print, $version, $text_only, $date, $html, $tidy, $add_ns, $verbose, $strict ); # used to check if the wrapping tags need to be output my $results = 0; my $file_results = 0; # first process the case where the user provides only # an xpath expression and a list of files if( @ARGV && ($ARGV[0] !~ m{^-}) ) { splice( @ARGV, 0, 0, '--group_by_file', 'file', '--pretty_print', 'indented', '--cond'); } GetOptions( 'help' => \$help, 'man' => \$man, 'Version' => \$version, 'cond=s' => \@paths, 'exclude|v=s' => \@exclude, 'root=s' => \@roots, 'files' => \$files, 'count' => \$count, 'nb_results=i' => \$nb_results, 'by_file=i' => \$nb_results_per_file, 'encoding=s' => \$encoding, 'wrap:s' => \$wrap, 'nowrap' => \$nowrap, 'descr:s' => \$descr, 'group_by_file:s' => \$group, 'pretty_print:s' => \$pretty_print, 'text_only' => \$text_only, 'date!' => \$date, 'strict' => \$strict, 'html' => \$html, 'tidy' => \$tidy, 'add_ns' => \$add_ns, 'verbose' => \$verbose, ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-exitstatus => 0, -verbose => 2) if $man; if( $version) { warn "$0 version $VERSION\n"; exit; } binmode STDOUT, ':utf8'; # case where options are given, but no root or path, assume the # first arg is a path if( !@roots and !@paths and !@exclude and @ARGV) { @paths= shift @ARGV; } unless( @roots or @paths or @exclude or $files) { pod2usage(1); exit; } if( ($files or $count) and !@paths) { pod2usage(1); exit; } if( ($files or $count) and (@roots or $encoding or defined( $wrap) or defined( $group) or defined( $pretty_print))) { pod2usage(1); exit; } if( $files and !@ARGV) { pod2usage(1); exit; } if( !$files and !$count and @paths and !@roots) { @roots= @paths; @paths=(); } $date=1 unless( defined $date); # defaults for optional arguments to options $group = 'file' if( defined $group and !$group); $pretty_print = 'indented' if( defined $pretty_print and !$pretty_print); if( $nowrap) { $wrap=''; } elsif( !defined( $wrap) and (@roots or @paths)) { $wrap= 'xml_grep'; } if( !defined( $descr) and (@roots or @paths)) { if( $date) { $date= localtime(); $descr = qq{version="$VERSION" date="$date"} } else { $descr = qq{version="$VERSION"}; } } # some globals my $current_file; my $count_file = 0; my $count_total = 0; my $nb_results_left_in_current_file=0; # will be used to create the twig my %options; if( $count) { my $twig_roots={}; my $twig_root= sub { $count_file++; $_[0]->purge; }; foreach my $path (@paths) { $twig_roots->{$path}= $twig_root; } $options{twig_roots}= $twig_roots; } elsif( @exclude) { # general options $nowrap=1; # twig options $options{twig_print_outside_roots} = 1; my $root_handlers={}; foreach my $exclude (@exclude) { $root_handlers->{$exclude}= sub { }; } $options{twig_roots}= $root_handlers; } else { create_regular_handlers( \%options, \@roots, \@paths); } if( $tidy) { $html= 1; $options{use_tidy}= 1; } $options{pretty_print} = $pretty_print if( $pretty_print); $options{output_encoding} = $encoding if( $encoding); my $t= create_twig( %options); if( @ARGV) { foreach my $file (@ARGV) { $current_file= $file; if( $nb_results_per_file) { $nb_results_left_in_current_file= $nb_results_per_file; } if( $verbose) { warn "parsing '$file'\n"; } my $ok= $html && ($current_file=~ m{^(http|ftp|file)://}) ? $t->safe_parseurl_html( $file) : ($current_file=~ m{^(http|ftp|file)://}) ? $t->safe_parseurl( $file) : $html ? $t->safe_parsefile_html( $file) : $t->safe_parsefile( $file); if( !$ok) { if( $@ =~ m{XMLGREP: FOUND}) { # in files mode print $current_file, "\n"; $nb_results--; exit unless( $nb_results); } elsif( $@ =~ m{^XMLGREP: NB_RESULT_REACHED}) { print file_result_end() if( $group && $file_results); print result_end() if( $results); exit; } else { $@ ||= 'unknown cause'; if( $strict) { die $@; } warn $@; if( !$count) { print "\n"; } } } if( $count) { print "$current_file: $count_file\n"; $count_total += $count_file; $count_file=0; } elsif( @roots) { print file_result_end() if( $file_results); } elsif( $count) { print "$count_total matches\n"; } } if( $count) { print "total: $count_total\n"; } print result_end() if( $results); } else { $file_results=0; my $ok= $t->safe_parse( \*STDIN); if( !$ok and ( $@ !~ m{^XMLGREP: NB_RESULT_REACHED})) { if( !$strict) { warn $@; } else { die $@; } } if( $count) { print "$count_total matches\n"; } else { print result_end(); } } sub create_regular_handlers { my( $options, $roots, $paths)= @_; if( @$roots) { my $root_handlers={}; my $root_handler= twig_roots_handler( @$paths); foreach my $root (@$roots) { $root_handlers->{$root}= $root_handler; } $options->{twig_roots}= $root_handlers; } if( @$paths) { my $twig_handlers={}; my $twig_handler= twig_handlers(); foreach my $path (@$paths) { $twig_handlers->{$path}= $twig_handler; } $options->{twig_handlers}= $twig_handlers; } } sub create_twig { my( %options)= @_; my $twig; eval { $twig= XML::Twig->new( %options) }; if( $@) { # see if we are in the case where the only condition uses string() or regexp if( ($@=~ m{^(regexp|string\(\)) condition not supported on twig_roots option}) && $options{twig_roots} && !$options{twig_handlers} && ( keys %{$options{twig_roots}} == 1) ) { # in this case add the proper twig_roots option my $cond= (keys %{$options{twig_roots}})[0]; (my $root= $cond)=~ s{\[[^\]]*\]$}{}; #warn "cond: '$cond' - root: '$root'\n"; delete $options{twig_roots}; delete $options{twig_handlers}; @paths= ($cond); @roots= ($root); create_regular_handlers( \%options, \@roots, \@paths); return create_twig( %options); } elsif( $@=~ m{^wrong condition: unrecognized expression in handler: '(.*?)'}) { die "error in filter condition '$1'\n"; } else { die "error: $@"; } } return $twig; } sub twig_roots_handler { my( @paths)= @_; return sub { my( $t, $root)= @_; if( !@paths or $_->att( '#print')) { print result_start() if( !$results); print file_result_start() if( $group && !$file_results); if( $text_only) { print $root->text, "\n"; } else { $root->print; } if( ! -- $nb_results) { $@= "XMLGREP: NB_RESULT_REACHED"; die; } if( ! -- $nb_results_left_in_current_file) { $t->finish_now(); } } $t->purge; 1; }; } sub twig_handlers { if( $files) { return sub { $@="XMLGREP: FOUND"; die; }; } else { return sub { my( $t, $hit)= @_; foreach my $elt ( $hit->ancestors_or_self) { $elt->set_att( '#print' => 1); } 1; }; } } sub result_start { $results=1; return if( $text_only); my $enc_decl= $encoding ? qq{encoding="$encoding" } : ''; return $wrap ? qq{\n<$wrap $descr>\n} : ''; } sub result_end { my $result; return if( $text_only); if( !$group) { $result= "\n"; } $result .= qq{\n} if( $wrap); return $result; } sub file_result_start { $file_results=1; return if( $text_only); my $result; $result= qq{<$group filename="$current_file">}; if( !$pretty_print) { $result.= "\n"; } return $result; } sub file_result_end { $file_results=0; return '' if( $text_only); return qq{\n\n}; } __END__ =head1 NAME xml_grep - grep XML files looking for specific elements =head1 SYNOPSYS xml_grep [options] or xml_grep By default you can just give C an XPath expression and a list of files, and get an XML file with the result. This is equivalent to writing xml_grep --group_by_file file --pretty_print indented --cond =head1 OPTIONS =over 4 =item B<--help> brief help message =item B<--man> full documentation =item B<--Version> display the tool version =item B<--root> look for and return xml chunks matching if neither C<--root> nor C<--file> are used then the element(s) that trigger the C<--cond> option is (are) used. If C<--cond> is not used then all elements matching the are returned several C<--root> can be provided =item B<--cond> return the chunks (or file names) only if they contain elements matching several C<--cond> can be provided (in which case they are OR'ed) =item B<--files> return only file names (do not generate an XML output) usage of this option precludes using any of the options that define the XML output: C<--roots>, C<--encoding>, C<--wrap>, C<--group_by_file> or C<--pretty_print> =item B<--count> return only the number of matches in each file usage of this option precludes using any of the options that define the XML output: C<--roots>, C<--encoding>, C<--wrap>, C<--group_by_file> or C<--pretty_print> =item B<--strict> without this option parsing errors are reported to STDOUT and the file skipped =item B<--date> when on (by default) the wrapping element get a C attribute that gives the date the tool was run. with C<--nodate> this attribute is not added, which can be useful if you need to compare 2 runs. =item B<--encoding> encoding of the xml output (utf-8 by default) =item B<--nb_results> output only results =item B<--by_file> output only results by file =item B<--wrap> wrap the xml result in the provided tag (defaults to 'xml_grep') If wrap is set to an empty string (C<--wrap ''>) then the xml result is not wrapped at all. =item B<--nowrap> same as using C<--wrap ''>: the xml result is not wrapped. =item B<--descr> attributes of the wrap tag (defaults to C<< version="" date="" >>) =item B<--group_by_file> wrap results for each files into a separate element. By default that element is named C. It has an attribute named C that gives the name of the file. the short version of this option is B<-g> =item B<--exclude> same as using C<-v> in grep: the elements that match the condition are excluded from the result, the input file(s) is (are) otherwise unchanged the short form of this option is B<-v> =item B<--pretty_print> pretty print the output using XML::Twig styles ('C', 'C' or 'C' are probably what you are looking for) if the option is used but no style is given then 'C' is used short form for this argument is B<-s> =item B<--text_only> Displays the text of the results, one by line. =item B<--html> Allow HTML input, files are converted using HTML::TreeBuilder =item B<--Tidy> Allow HTML input, files are converted using HTML::Tidy =back =head2 Condition Syntax is an XPath-like expression as allowed by XML::Twig to trigger handlers. exemples: 'para' 'para[@compact="compact"]' '*[@urgent]' '*[@urgent="1"]' 'para[string()="WARNING"]' see XML::Twig for a more complete description of the syntax options are processedby Getopt::Long so they can start with '-' or '--' and can be abbreviated (C<-r> instead of C<--root> for example) =head1 DESCRIPTION B does a grep on XML files. Instead of using regular expressions it uses XPath expressions (in fact the subset of XPath supported by XML::Twig) the results can be the names of the files or XML elements containing matching elements. =head1 SEE ALSO XML::Twig Getopt::Long =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Michel Rodriguez XML-Twig-3.50/tools/xml_pp/0000755000175000017500000000000012637027512015717 5ustar mrodrigumrodriguXML-Twig-3.50/tools/xml_pp/xml_pp0000755000175000017500000001751612346001777017160 0ustar mrodrigumrodrigu#!/usr/bin/perl -w # $Id: /xmltwig/trunk/tools/xml_pp/xml_pp 32 2008-01-18T13:11:52.128782Z mrodrigu $ use strict; use XML::Twig; use File::Temp qw/tempfile/; use File::Basename qw/dirname/; my @styles= XML::Twig->_pretty_print_styles; # from XML::Twig my $styles= join '|', @styles; # for usage my %styles= map { $_ => 1} @styles; # to check option my $DEFAULT_STYLE= 'indented'; my $USAGE= "usage: $0 [-v] [-i] [-s ($styles)] [-p ] [-e ] [-l] [-f ] []"; # because of the -i.bak option I don't think I can use one of the core # option processing modules, so it's custom handling and no clusterization :--( my %opt= process_options(); # changes @ARGV my @twig_options=( pretty_print => $opt{style}, error_context => 1, ); if( $opt{preserve_space_in}) { push @twig_options, keep_spaces_in => $opt{preserve_space_in};} if( $opt{encoding}) { push @twig_options, output_encoding => $opt{encoding}; } else { push @twig_options, keep_encoding => 1; } # in normal (ie not -l) mode tags are output as soon as possible push @twig_options, twig_handlers => { _all_ => sub { $_[0]->flush } } unless( $opt{load}); if( @ARGV) { foreach my $file (@ARGV) { print STDERR "$file\n" if( $opt{verbose}); my $t= XML::Twig->new( @twig_options); my $tempfile; if( $opt{in_place}) { (undef, $tempfile)= tempfile( DIR => dirname( $file)) or die "cannot create tempfile for $file: $!\n" ; open( PP_OUTPUT, ">$tempfile") or die "cannot create tempfile $tempfile: $!"; select PP_OUTPUT; } $t= $t->safe_parsefile( $file); if( $t) { if( $opt{load}) { $t->print; } select STDOUT; if( $opt{in_place}) { close PP_OUTPUT; my $mode= mode( $file); if( $opt{backup}) { my $backup= backup( $file, $opt{backup}); rename( $file, $backup) or die "cannot create backup file $backup: $!"; } rename( $tempfile, $file) or die "cannot overwrite file $file: $!"; if( $mode ne mode( $file)) { chmod $mode, $file or die "cannot set $file mode to $mode: $!"; } } } else { if( defined $tempfile) { unlink $tempfile or die "cannot unlink temp file $tempfile: $!"; } die $@; } } } else { my $t= XML::Twig->new( @twig_options); $t->parse( \*STDIN); if( $opt{load}) { $t->print; } } sub mode { my( $file)= @_; return (stat($file))[2]; } sub process_options { my %opt; while( @ARGV && ($ARGV[0]=~ m{^-}) ) { my $opt= shift @ARGV; if( ($opt eq '-v') || ($opt eq '--verbose') ) { die $USAGE if( $opt{verbose}); $opt{verbose}= 1; } elsif( ($opt eq '-s') || ($opt eq '--style') ) { die $USAGE if( $opt{style}); $opt{style}= shift @ARGV; die $USAGE unless( $styles{$opt{style}}); } elsif( ($opt=~ m{^-i(.*)$}) || ($opt=~ m{^--in_place(.*)$}) ) { die $USAGE if( $opt{in_place}); $opt{in_place}= 1; $opt{backup}= $1 ||''; } elsif( ($opt eq '-p') || ($opt eq '--preserve') ) { my $tags= shift @ARGV; my @tags= split /\s+/, $tags; $opt{preserve_space_in} ||= []; push @{$opt{preserve_space_in}}, @tags; } elsif( ($opt eq '-e') || ($opt eq '--encoding') ) { die $USAGE if( $opt{encoding}); $opt{encoding}= shift @ARGV; } elsif( ($opt eq '-l') || ($opt eq '--load')) { die $USAGE if( $opt{load}); $opt{load}=1; } elsif( ($opt eq '-f') || ($opt eq '--files') ) { my $file= shift @ARGV; push @ARGV, files_from( $file); } elsif( ($opt eq '-h') || ($opt eq '--help')) { system "pod2text", $0; exit; } elsif( $opt eq '--') { last; } else { die $USAGE; } } $opt{style} ||= $DEFAULT_STYLE; return %opt; } # get the list of files (one per line) from a file sub files_from { my $file= shift; open( FILES, "<$file") or die "cannot open file $file: $!"; my @files; while( ) { chomp; push @files, $_; } close FILES; return @files; } sub backup { my( $file, $extension)= @_; my $backup; if( $extension=~ m{\*}) { ($backup= $extension)=~ s{\*}{$file}g; } else { $backup= $file.$extension; } return $backup; } __END__ =head1 NAME xml_pp - xml pretty-printer =head1 SYNOPSYS xml_pp [options] [] =head1 DESCRIPTION XML pretty printer using XML::Twig =head1 OPTIONS =over 4 =item -i[] edits the file(s) in place, if an extension is provided (no space between C<-i> and the extension) then the original file is backed-up with that extension The rules for the extension are the same as Perl's (see perldoc perlrun): if the extension includes no "*" then it is appended to the original file name, If the extension does contain one or more "*" characters, then each "*" is replaced with the current filename. =item -s

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( '
foobar')->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{foobarbazfoobar}; 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{foobarbaz}; 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, '