XML-Smart-1.78/0000755000175000017500000000000012214355545012521 5ustar harishharishXML-Smart-1.78/Changes0000644000175000017500000001723112214354071014011 0ustar harishharishRevision history for Perl extension XML::Smart. 1.78 2013-9-12 - Fixed hash randomization bug Id:84929 - lib/XML/Smart.pm: Formatting update, no changes to code. - lib/XML/Smart/Data.pm: Fixed hash randomization bug Id:84929 - lib/XML/Smart/Tree.pm: Formatting update, no changes to code. - Updated the following files to reflect bug fix: t/base_tests.t t/base_tests_for_mem_leak.t t/base_tests_for_objcopy.t t/base_tests_multi_obj.t t/special_char_from_url.t - Added License to Makefile.PL - Fixed warnigns bug id:84006 - Fixed pod errors. 1.77 2013-2-13 - Rewrote tests with Test::More to prevent fails in OpenBSD, Fedora and some versions of Win. 1.76 2013-2-05 - Fixed dependency fail by skipping author tests. 1.75 2013-2-05 - Fixed dependency fail by adding prerequisite 'Object::MultiType' => 0.03 1.74 2013-2-04 - Fixed POD errors - Removed unnecessary modules from tests. - Removed warnings from Tree and Tie - Removed Binary data from Smart.pm - Added or croak to all file open()s 1.73 2013-1-28 - Fixed bug 17834 in Tree.pm - Fixed object copy bug 34695 - Updated POD to reflect where obj copy is not supported. - Fixed object Deep copy bug ( bug id 56806 ) - Fixed Mem leak and added tests. - Added ANNIHILATE for better object destruction - Fixed Encoding errors, added tests and added to pod 1.71 2013-1-26 - Updated all pm to use strict and warnings - Updated tests to use strict and warnings - Added basic tests such as load - Moved tests to t/ - Gramatical Corrections to POD - Removed binary data from POD ( bug id 53321 ) - Updated list of binary data thats handled. - Tree.pm updated to allow warnings after usage ( patch from bug ticket id: 27310 ) - XML encoding declaration changed from utf-8 to UTF-8 ( bug id 76668 ) - Fixed URL tests ( bug id 34562 fix provided ) - Check added for existence of object in destructor ( bug id 62091 fix provided ) 1.6.9 2004-9-21 - dump_tree() and similars methods will dump hash keys sorted now. - Hooks on_start, on_char and on_end for the parser will receive the parser object too. 1.6.8 2004-8-3 - Fixed minor bug for order of keys and new multiple elements. - Fixed assigment of content with the method content() for new trees. - Added order to the attributes when using apply_dtd(). - Fixed apply_dtd() when we have an ELEMENT and an ATTRIBUTE with the same name. 1.6.7 2004-7-19 - Fixed minor bug with internal flag {null}. use as a boolean, and not as defined {null} changed. - Fixed minor bug with data_pointer() and root element name. 1.6.6 2004-7-8 - Fixed minor bug on content order for multiple contents and null contents chunks. - Fixed wrong creation of key in the tree when using is_node() for null pointers. 1.6.5 2004-5-29 - Fixed some minor bug for the bugged Perl 5.8.0. 1.6.4 2004-5-29 - ReFixed minor bug on internal function _is_unicode(). 1.6.3 2004-5-29 - Fixed minor bug on internal function _is_unicode(). 1.6.2 2004-5-28 - Fixed minor bug on XML::Smart::DTD. 1.6.1 2004-5-26 - Added support to DTD: new method apply_dtd(). - Fixed bug when values are XML::Smart objects and the key order. - Fixed bug with creation of null trees and orders of already existing keys. - Added FAQ and Tutorial documents for XML::Smart. 1.6 2004-5-9 - Fixed minor bug with search of attributes when they are as contents. 1.5.9 2004-4-12 - Fixed minor bug with null trees and arrays. 1.5.8 2004-4-11 - Added methods tree_ok(), tree_pointer_ok(), pointer_ok(), dump_tree(), dump_tree_pointer(), dump_pointer(). - Fixed position of CONTENT for single content with tags when creating the XML data(). - Fixed comment handling: 1.5.7 2004-03-23 - Fixed minor bug with BINARY data and XML::Parser, that handles each line of a content as a multiple content. * Thanks to Rusty Allen for the extensive tests of CDATA and BINARY handling of XML::Smart. 1.5.6 2004-03-23 - Fixed minor mistake on set_cdata() method and cdata id inside data(). 1.5.5 2004-03-23 - Added methods set_auto() , set_auto_node(), set_binary(), set_cdata(). - Fixed bug on copy(). - Fixed bug with data() when CONTENT key is found and should be CDATA or BINARY. 1.5.4 2004-02-23 - Added autoload of parts of the module, to save load memory. 1.5.3 2004-02-23 - Just minor changes and fixes. 1.5.2 2004-02-15 - Fixed some minor bug on PUSH and UNSHIFT. - Added support for multiple nodes for the same tag and interpolation of different nodes. - Removed duplicated entry of '/.CONTENT/0' at '/order' key. - Added new tests and revision of the previous tests. 1.5.1 2004-02-05 - Fixed simple bug when XML::Smart object used on recursions/loops. 1.5 2004-01-15 - Added method aliase tree_pointer(). - Added method root(). - Added event handlers: on_start, on_char, on_end. - Multiple contents handled in different way. $xml->{CONTENT} is tied and the data will be at $xml->{'/.CONTENT/0} , $xml->{'/.CONTENT/1} , $xml->{'/.CONTENT/2}... - data() will keep the multiple contents order. - content(i , data) can be used to set a content part. - $srt = content() returns all the multiple contents grouped. 1.4.1 25/10/2003 - Fixed set_node(). Not full implemented on previous version! sorry. - Fixed openned tags for XML::Smart::HTMLParser. Now closing near the open tag. - Fixed external access of /nodes and /order, avoiding internal handling of them as normal keys. - Fixed bug at nodes(), nodes_keys(), args(), to identify HASH/ARRAY ref(). - Fixed bug at XML::Smart::HTMLParser, when an attribute value has 2 '>' inside. - Fixed prerequisite at test.pl. - Fixed warnings. 1.4 10/10/2003 - Fixed bug for {arg}{CONTENT}, when {arg} not defined yet. - An argument now can be forced/unforced to be a node (tag) when XML data is generated. - Generation of XML data now keep the elements order, based in the previous document loaded or in the elements creation. - Added multiple searches at the same time to find(). - Fixed delete {arg}[0]. - Fixed pointer() when pointing to a content. - Fixed some others minor bugs. - New methods: nodes(), nodes_keys(), args(), args_values(), set_node(), set_order(), path(), path_as_xpath(), xpath(), xpath_pointer(). 1.3.1 18/06/2003 - Just a bug fix in XML::Smart::Parser for CDATA. 1.3 15/06/2003 - Can build/load Wild XML data (like HTML). - New methods: null(), key(), i(). - Fixed select search with multiple values. And added support to search in keys, not only ARRAY ref. - Accept a XML::Smart object as a value in the tree. When parsing to generate the data, the XML::Smart->tree is got. - Upgrade to Object::MultiType 0.2, due a bug when using XML::Smart as a boolean. 1.2 Mon May 30 02:03:00 2003 - Added cut_root(), base(), back(), copy() and data_pointer() methods. - New resource "return format". - Support for basic entities (defaults). - Added Support for URLs (with LWP::UserAgent). - Unicode (UTF-8) support. (Work only on Perl-5.8+) - Added support for binary and CDATA content and automatically detection of both. - Added meta generator tag. - Fixed bug in XML::Smart::Parser (XML::Parser::Lite). Break of REGEX parser on sub REGEX execution. - Fixed bug with quotes. 1.1 Mon May 23 03:12:12 2003 - Fixed some bugs. 1.0 Mon May 12 11:02:48 2003 - First release! - original version; created by h2xs 1.21 with options -X -A -n XML::Smart XML-Smart-1.78/MANIFEST0000644000175000017500000000230412214355545013651 0ustar harishharishREADME Changes MANIFEST Makefile.PL t/pod.t t/hex.t t/00-load.t t/manifest.t t/copy_fail.t t/base_tests.t t/boilerplate.t t/pod-coverage.t t/encode_tests.t t/obj_copy_meta.t t/subtree_assign.t t/force_case_bug_fix.t t/base_tests_multi_obj.t t/base_tests_for_objcopy.t t/base_tests_for_mem_leak.t data_for_tests/Tamil.data data_for_tests/Spanish.data data_for_tests/Random.data data_for_tests/winSpecial.data data_for_tests/German.data data_for_tests/Chinese.data data_for_tests/bug_andpersand.data data_for_tests/bug_arabic.data data_for_tests/Japanese.data data_for_tests/French.data data_for_tests/umlaut.data data_for_tests/Russian.data data_for_tests/Portuguese.data data_for_tests/URLChars.data lib/XML/Smart.pm lib/XML/Smart/Tutorial.pod lib/XML/Smart/Parser.pm lib/XML/Smart/FAQ.pod lib/XML/Smart/XPath.pm lib/XML/Smart/Tutorial.epod lib/XML/Smart/Tie.pm lib/XML/Smart/Base64.pm lib/XML/Smart/DTD.pm lib/XML/Smart/HTMLParser.pm lib/XML/Smart/Tree.pm lib/XML/Smart/FAQ.epod lib/XML/Smart/Entity.pm lib/XML/Smart/Data.pm lib/XML/Smart/Shared.pm META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) XML-Smart-1.78/META.json0000664000175000017500000000170412214355545014146 0ustar harishharish{ "abstract" : "A smart, easy and powerful way to access or create XML from fiels, data and URLs.", "author" : [ "Graciliano M. P. " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.112621", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "XML-Smart", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "Test::More" : 0 } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : 0 } }, "runtime" : { "requires" : { "Object::MultiType" : "0.03", "perl" : "5.006" } } }, "release_status" : "stable", "version" : "1.78" } XML-Smart-1.78/META.yml0000664000175000017500000000106412214355545013775 0ustar harishharish--- abstract: 'A smart, easy and powerful way to access or create XML from fiels, data and URLs.' author: - 'Graciliano M. P. ' build_requires: Test::More: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.112621' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: XML-Smart no_index: directory: - t - inc requires: Object::MultiType: 0.03 perl: 5.006 version: 1.78 XML-Smart-1.78/t/0000755000175000017500000000000012214355545012764 5ustar harishharishXML-Smart-1.78/t/encode_tests.t0000644000175000017500000000563212111111410015607 0ustar harishharishuse strict ; use warnings ; use Test::More ; use XML::Smart ; use open ':encoding(utf8)'; our $directory = 'data_for_tests'; opendir ( my $_data_dir, $directory) or die $!; while (my $file = readdir( $_data_dir ) ) { next if( $file eq '.' ) ; next if( $file eq '..' ) ; next if( $file =~ '.svn' ) ; next if( $file =~ /^bug/ ) ; subtest "Testing inclusion of data into xml $file" => sub { _test_data_from( $file ) ; done_testing() ; }; subtest "Testing embed of data into xml $file" => sub { _test_embed_from( $file ) ; done_testing() ; } } done_testing() ; #################################################################################################### ## Helper Functions ## #################################################################################################### sub _test_embed_from { my $infile = shift ; $infile = $directory . "/" . $infile ; open( my $_infile, $infile ) or die ( $! ) ; my @in_data = <$_infile> ; my $in_data = join( "", @in_data ) ; close( $_infile ) ; my $xml_input = ' ' . $in_data . ' '; my $xml_obj = new XML::Smart( $xml_input ) ; my $data = $xml_obj->data( 'decode' => 1 , 'noheader' => 1 , ) ; $data =~ s/\n//gs; $data =~ s/\s+/ /gs; $xml_input =~ s/\n//gs; $xml_input =~ s/\s+/ /gs; cmp_ok( $data, 'eq', $xml_input ) ; } sub _test_data_from { my $infile = shift ; $infile = $directory . "/" . $infile ; open( my $_infile, $infile ) or die ( $! ) ; my @in_data = <$_infile> ; my $in_data = join( "", @in_data ) ; close( $_infile ) ; my @utf8_array = ( $in_data, "GOOD DATA" ) ; my $utf8 = \@utf8_array ; my $response_xml ; my $xml_obj = XML::Smart->new() ; eval{ $xml_obj->{ response }{ data } = $utf8 ; }; if( $@ ){ fail( "Hash Creation Error $@" ) ; } eval{ $response_xml = $xml_obj->data() ; }; if( $@ ){ fail( "XML Creation Error $@" ) ; } my $post_xml_data = _get_data_from_xml( $response_xml ) ; my $post_xml_in_data = $post_xml_data->{ response }{ data }->[0]->{ CONTENT } ; cmp_ok( $post_xml_in_data, 'eq', $in_data ) ; return 1 ; } sub _get_data_from_xml { my $xml = shift ; my $data_obj ; eval { $data_obj = XML::Smart->new( $xml ); }; if( $@ ) { $xml =~ s/[^[:print:]]+//g ; $data_obj = XML::Smart->new( $xml ); } my $data_hash = $data_obj->tree(); return $data_hash; } XML-Smart-1.78/t/subtree_assign.t0000644000175000017500000000127712110211431016151 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test::More ; use ExtUtils::MakeMaker ; use XML::Smart ; my $xml_base = new XML::Smart(q` TEXT1 & more aaa bbb ` ) ; my $xml_to_add = new XML::Smart(q` TEXT1 & more aaa bbb ` ) ; $xml_base->{ root }{ level1 } = $xml_to_add->{ root }{ level12 } ; cmp_ok( $xml_base->data( noheader=> 1 ), 'eq', q` TEXT1 & more bbb bbb ` ); done_testing() ; XML-Smart-1.78/t/base_tests_for_objcopy.t0000644000175000017500000011513012214343274017675 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test::More ; use ExtUtils::MakeMaker ; use XML::Smart ; my $DATA = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; ##if (0) { ######################### subtest 'HTML Tests' => sub { my $XML = XML::Smart->new( q` Blah blah


` ); $XML = $XML->copy() ; my $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok($data, 'eq', q` Blah blah


`) ; my @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'input br input br') ; $XML->{html}{body}{form}->set_order( qw(br input input br) ) ; @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'br input input br') ; $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok( $data, 'eq', q` Blah blah


`) ; done_testing() ; } ; subtest 'Pointer Tests' => sub { my $XML = XML::Smart->new(q` content0 sub_content content1 content2 ` , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; cmp_ok($data, 'eq', q` content0 sub_content content1 content2 `) ; my $tmp = tied $XML->{root}->pointer->{CONTENT} ; isnt( tied $XML->{root}->pointer->{CONTENT}, undef ) ; my $cont = $XML->{root}->{CONTENT} ; cmp_ok($cont, 'eq', q` content0 content1 content2 `) ; my $cont_ = $XML->{root}->content ; cmp_ok( $cont_, 'eq', q` content0 content1 content2 `) ; $XML->{root}->content(1,"set1") ; my @cont = $XML->{root}->content ; cmp_ok($cont[0], 'eq', "\ncontent0\n") ; cmp_ok($cont[1], 'eq', "set1") ; cmp_ok($cont[2], 'eq', "\ncontent2\n") ; $XML->{root}->{CONTENT} = 123 ; my $cont_2 = $XML->{root}->content ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $cont_2, '==', 123) ; is( tied $XML->{root}->pointer->{CONTENT}, undef ) ; done_testing() ; } ; is( tied $XML->{root}{tag1}{sub}->pointer->{CONTENT}, undef, 'Undefined' ) ; my $sub_cont = $XML->{root}{tag1}{sub}->{CONTENT} ; cmp_ok($sub_cont, 'eq', 'sub_content') ; $data = $XML->data(noheader => 1) ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $data , 'eq', q`123 sub_content ` ) ; done_testing() ; }; done_testing() ; } ; subtest 'Content Set tests' => sub { my $xml = new XML::Smart(q` aaa bbb `) ; $xml = $xml->copy() ; $xml = $xml->{root} ; $xml->{phone}->content('XXX') ; $xml->{phone}[1]->content('YYY') ; $xml->{test}->content('ZZZ') ; my $data = $xml->data(noheader => 1) ; cmp_ok($data, 'eq', q` XXX YYY ZZZ `) ; done_testing() ; } ; subtest 'Data Order Tests' => sub { my $xml = new XML::Smart(q` TEXT1 & more aaa bbb `,'html') ; $xml = $xml->copy() ; my $data = $xml->data(noident=>1 , noheader => 1 , wild=>1) ; cmp_ok($data, 'eq', q` TEXT1 & more aaa bbb `) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tests' => sub { my $XML = XML::Smart->new('text1foobartext2' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//g ; cmp_ok($data, 'eq', 'text1foobartext2') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nometagen tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $data = $XML->data(nometagen => 1) ; $data =~ s/\s//gs ; my $data_org = $DATA ; $data_org =~ s/\s//gs ; cmp_ok( $data, 'eq', $data_org) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::HTMLParser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '' ) ; $XML = XML::Smart->new(q` TITLE end" w=q> FOO2-DATA ` , 'HTML') ; $XML = $XML->copy() ; $data = $XML->data(noheader => 1 , nospace => 1 ) ; cmp_ok($data, 'eq', q`TITLEFOO2-DATA`) ; $XML = XML::Smart->new(q` TITLE ` , 'HTML') ; $XML = $XML->copy() ; $data = $XML->data(noheader => 1 , nospace => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', q`TITLE`); done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser args Tests' => sub { TODO: { local $TODO = "object copy persist wild char state not implemeted" ; my $XML = XML::Smart->new(q` <.sub1 arg="1" x=1 /> <.sub2 arg="2"/> content ` , 'XML::Smart::HTMLParser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1 , wild => 1) ; cmp_ok( $data, 'eq', q` <.sub1 arg="1" x="1"/> <.sub2 arg="2"/> content `); } done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tree tests' => sub { my $XML0 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; $XML0 = $XML0->copy() ; my $XML1 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; $XML1 = $XML1->copy() ; my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{sub}{sub2} = $XML0->tree ; push(@{$XML->{sub}{sub2}} , $XML1->tree ) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML = $XML->{hosts} ; my $addr = $XML->{server}[0]{address} ; cmp_ok($addr, 'eq', '192.168.0.1') ; my $addr0 = $XML->{server}[0]{address}[0] ; cmp_ok( $addr, 'eq', $addr0); my $addr1 = $XML->{server}{address}[1] ; cmp_ok( $addr1, 'eq', '192.168.0.2') ; my $addr01 = $XML->{server}[0]{address}[1] ; cmp_ok( $addr1, 'eq', $addr01); my @addrs = @{$XML->{server}{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); @addrs = @{$XML->{server}[0]{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr, 'eq', '192.168.1.10') ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr, 'eq', $addr0) ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.1.20') ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok( $type, 'eq', 'conectiva') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok( $addr, 'eq', '192.168.2.100') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok( $addr0, 'eq', $addr) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Args Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML = $XML->{hosts} ; $XML = $XML->copy() ; my $newsrv = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; push(@{$XML->{server}} , $newsrv) ; my $addr0 = $XML->{'server'}('type','eq','mandrake'){'address'}[0] ; cmp_ok( $addr0, 'eq', '192.168.3.201') ; $XML->{'server'}('type','eq','mandrake'){'address'}[1] = '192.168.3.202' ; $XML = $XML->copy() ; my $addr1 = $XML->{'server'}('type','eq','mandrake'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.3.202') ; push(@{$XML->{'server'}('type','eq','conectiva'){'address'}} , '192.168.2.101') ; $addr1 = $XML->{'server'}('type','eq','conectiva'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; $addr1 = $XML->{'server'}[2]{'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; done_testing() ; } ; ######################### subtest 'Args regex Match Tests' => sub { my $XML = XML::Smart->new(q` ` , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my @users = $XML->{users}('email','=~','^jo') ; cmp_ok( $users[0]->{name}, 'eq', 'Joe X') ; cmp_ok( $users[1]->{name}, 'eq', 'JoH Y') ; done_testing() ; } ; ######################### subtest 'Default Parser Array Test' => sub { my $XML = XML::Smart->new() ; $XML->{server} = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; $XML = $XML->copy() ; $XML->{server}{address}[1] = '192.168.3.202' ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.3.201
192.168.3.202
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser tags Test' => sub { my $XML = XML::Smart->new('ctab' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = qq`ctab` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser data() options tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML->{'hosts'}{'server'}('type','eq','conectiva'){'address'}[1] = '' ; $XML = $XML->copy() ; my $data = $XML->data( noident => 1 , nospace => 1 , lowtag => 1 , upertag => 1 , uperarg => 1 , noheader => 1 , ) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data populate test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML->{data} = 'aaa' ; $XML->{var } = 10 ; $XML->{addr} = [qw(1 2 3)] ; $XML = $XML->copy() ; my $data = $XML->data(length => 1 , nometagen => 1 ) ; $data =~ s/\s//gs ; my $dataok = q`123`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data Populate Array test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML->{hosts}{server} = { os => 'lx' , type => 'red' , ver => 123 , } ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; $XML = $XML->copy() ; $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $srv = { os => 'lx' , type => 'red' , ver => 123 , } ; push( @{$XML->{hosts}} , {XXXXXX => 1}) ; unshift( @{$XML->{hosts}} , $srv) ; push( @{$XML->{hosts}{more}} , {YYYY => 1}) ; $XML = $XML->copy() ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML->{hosts}{server} = [ { os => 'lx' , type => 'a' , ver => '1' ,} , { os => 'lx ', type => 'b' , ver => '2' ,} , ]; $XML = $XML->copy() ; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'a' ) ; my $srv0 = shift( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv0{type}, 'eq', 'a' ) ; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}[0]{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}[0]{server}[0]{type}[0], 'eq', 'b' ) ; my $srv1 = pop( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv1{type}, 'eq', 'b' ) ; my $data = $XML->data(noheader => 1 , nospace=>1) ; cmp_ok($data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser' ) ; $XML = $XML->copy() ; my @types = $XML->{hosts}{server}('[@]','type') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; $XML = $XML->copy() ; @types = $XML->{hosts}{server}{type}('<@') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my @srvs = $XML->{hosts}{server}('os','eq','linux') ; my @types ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva' ) ; $XML = $XML->copy() ; @srvs = $XML->{hosts}{server}(['os','eq','linux'],['os','eq','bsd']) ; @types = () ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data encode test' => sub { my $wild = pack("C", 127 ) ; my $data = qq`$wild`; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $XML = $XML->copy() ; cmp_ok( $XML->{code}, 'eq', $wild ) ; $data = $XML->data() ; $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $XML = $XML->copy() ; cmp_ok( $XML->{code}, 'eq', $wild ) ; my $data2 = $XML->data() ; cmp_ok( $data, 'eq', $data2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $addr1 = $XML->{hosts}{server}{address} ; $XML = $XML->copy() ; my $XML2 = $XML->cut_root ; my $addr2 = $XML2->{server}{address} ; cmp_ok( $addr1, 'eq', $addr2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Funny Char test' => sub { my $data = q` My Company & Name + x >> plus " + '... `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $XML = $XML->copy() ; cmp_ok( $XML->{root}{foo}, 'eq', q` My Company & Name + x >> plus " + '...` ) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q` My Company & Name + x >> plus " + '...` ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nodes test' => sub { my $XML = XML::Smart->new(q` cont ` , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my @nodes = $XML->{root}{foo}->nodes ; cmp_ok( $nodes[0]->{arg}, 'eq', 'z') ; @nodes = $XML->{root}{foo}->nodes_keys ; cmp_ok( "@nodes", 'eq', 'bar' ) ; isnt( $XML->{root}{foo}{bar}->is_node, undef ) ; my @keys = $XML->{root}{foo}('@keys') ; cmp_ok("@keys", 'eq', 'arg1 arg2 bar' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser CDATA test' => sub { my $data = qq` end]]> `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $XML = $XML->copy() ; cmp_ok( $XML->{root}{item}{data}, 'eq', q`some CDATA code end` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Hash assign through array Test' => sub { my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{menu}{option}[0] = { name => "Help" , level => {from => 1 , to => 99} , } ; $XML = $XML->copy() ; $XML->{menu}{option}[0]{sub}{option}[0] = { name => "Busca" , level => {from => 1 , to => 99} , } ; $XML = $XML->copy() ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q``) ; done_testing() ; } ; ######################### subtest 'Default Parser integer data tests' => sub { my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{menu}{arg1} = 123 ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg2}{subarg} = 999 ; $XML = $XML->copy() ; cmp_ok($XML->{menu}{arg1}, '==', 123 ) ; cmp_ok($XML->{menu}{arg2}, '==', 456 ) ; cmp_ok($XML->{menu}{arg2}{subarg}, '==', 999 ) ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`456` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Args get Test' => sub { my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{menu}{arg1} = [1,2,3] ; $XML->{menu}{arg2} = 4 ; $XML = $XML->copy() ; my @arg1 = $XML->{menu}{arg1}('@') ; cmp_ok( $#arg1, '==', 2 ) ; my @arg2 = $XML->{menu}{arg2}('@') ; cmp_ok( $#arg2, '==', 0 ) ; my @arg3 = $XML->{menu}{arg3}('@') ; cmp_ok( $#arg3, '==', -1 ) ; done_testing() ; } ; ######################### subtest 'Default Parser set_node and set_order Tests' => sub { my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg1} = 123 ; $XML = $XML->copy() ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; # Cannot copy object between set_node and set_node( 0 ) $XML->{menu}{arg2}->set_node ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`456` ) ; $XML->{menu}{arg2}->set_node(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}->set_order('arg1' , 'arg2') ; $XML = $XML->copy() ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; delete $XML->{menu}{arg2}[0] ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; done_testing() ; } ; ######################### subtest 'Default Parser XML Structure verification' => sub { my $XML = XML::Smart->new() ; $XML = $XML->copy() ; $XML->{root}{foo} = "bla bla bla"; $XML->{root}{foo}->set_node(1) ; $XML = $XML->copy() ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', '1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', 'HASH' ) ; $XML->{root}{foo}->set_node(0) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', '' ) ; is( $XML->tree->{root}{'/nodes'}{foo}, undef ) ; ## Cannot copy object between set_cdata( 1 ), set_node( 1 ), set_binary( 1 ) and unset of same. $XML->{root}{foo}->set_cdata(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT} , 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_auto_node ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 1 ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_cdata(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', 'HASH' ) ; $XML->{root}{foo}->set_auto ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', '' ) ; isnt( exists $XML->tree->{root}{'/nodes'}{foo}, undef ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and Bin data tests' => sub { my $XML = new XML::Smart ; $XML = $XML->copy() ; $XML->{root}{foo} = "bla bla bla bla bla"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', ' bla bla]]>' ) ; ## Cannot copy object between set_cdata( 1 ), set_node( 1 ), set_binary( 1 ) and unset of same. $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'bla bla bla <tag> bla bla' ) ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok ($data, 'eq', 'YmxhIGJsYSBibGEgPHRhZz4gYmxhIGJsYQ==' ) ; done_testing() ; } ; ######################### subtest 'Default Parser Funny Chars, Hex and Bin data Test' => sub { my $XML = new XML::Smart ; $XML = $XML->copy() ; $XML->{root}{foo} = "

test \x03

"; $XML = $XML->copy() ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; ## Cannot copy object between set_cdata( 1 ), set_node( 1 ), set_binary( 1 ) and unset of same. $XML->{root}{foo}->set_binary(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "<h1>test \x03\</h1>") ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA test' => sub { my $XML = new XML::Smart ; $XML = $XML->copy() ; $XML->{root}{foo} = "simple"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; $XML->{root}{foo}->set_cdata(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and funny chars' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "foo bar baz"; $XML = $XML->copy() ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'foo bar baz]]>' ) ; ## Cannot copy object between set_cdata( 1 ), set_node( 1 ), set_binary( 1 ) and unset of same. $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '<words>foo bar baz</words>' ) ; done_testing() ; } ; ######################### subtest 'Default Parser' => sub { my $XML = XML::Smart->new(q` here's a test `, 'XML::Parser'); $XML = $XML->copy() ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "here's a test") ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Path and XPath Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr->path, 'eq', '/hosts/server[1]/address' ) ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr0->path , 'eq', '/hosts/server[1]/address[0]') ; cmp_ok( $addr0->path_as_xpath , 'eq', '/hosts/server[2]/address') ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok($addr->path , 'eq', '/hosts/server[2]/address') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok($addr0->path , 'eq', '/hosts/server[2]/address[0]') ; cmp_ok($addr0->path_as_xpath , 'eq', '/hosts/server[3]/@address') ; $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; cmp_ok($type->path_as_xpath , 'eq', '/hosts/server[3]/@type') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root array Tests' => sub{ my $XML = new XML::Smart(q` 456 `,'smart'); $XML = $XML->copy() ; $XML = $XML->cut_root ; $XML = $XML->copy() ; my @frames_123 = @{ $XML->{'output'}('name','eq',123){'frames'} } ; my @formats_123 = map { $_->{'format'} } @frames_123 ; my @frames_456 = @{ $XML->{'output'}('name','eq',456){'frames'} } ; my @formats_456 = map { $_->{format} } @frames_456 ; cmp_ok( join(";", @formats_123) , 'eq', 'a;b' ) ; cmp_ok( join(";", @formats_456) , 'eq', 'c;d' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $html = q`

foo

`; my @tag ; my $p = XML::Smart::HTMLParser->new( Start => sub { shift; push(@tag , @_) ;}, Char => sub {}, End => sub {}, ); $p->parse($html) ; cmp_ok($tag[-1] , 'eq', '$s->{supply}->shift') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array pop Test' => sub { my $xml = new XML::Smart(q` test 1 test 2 test 3 file 1 `); $xml = $xml->copy() ; $xml->{doc}{port}[0] = 0; $xml->{doc}{port}[1] = 1; $xml = $xml->copy() ; $xml->{doc}{port}[2] = 2; $xml->{doc}{port}[3] = 3; $xml = $xml->copy() ; my $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`test 1test 2test 3file 10123`) ; pop @{$xml->{doc}{'/order'}} ; $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`test 1test 2test 3file 10123`) ; done_testing() ; } ; ######################### subtest 'XML::XPath Tests' => sub { eval(q`use XML::XPath`) ; if( $@ ) { plan skip_all => 'XML::XPath Unavailable' ; } my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->copy() ; my $xp1 = $XML->XPath ; my $xp2 = $XML->XPath ; cmp_ok( $xp1, 'eq', $xp2 ) ; $xp1 = $XML->XPath ; $XML->{hosts}{tmp} = 123 ; $XML = $XML->copy() ; $xp2 = $XML->XPath ; ## Test cache of the XPath object: cmp_ok( $xp1, '!=', $xp2 ) ; delete $XML->{hosts}{tmp} ; $XML = $XML->copy() ; my $data = $XML->XPath->findnodes_as_string('/') ; cmp_ok( $data, 'eq', q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`) ; done_testing() ; } ; ######################### subtest 'XML::Smart::DTD Tests' => sub { use XML::Smart::DTD ; my $dtd = XML::Smart::DTD->new(q` ]> `) ; isnt( $dtd->elem_exists('curso') , undef ) ; isnt( $dtd->elem_exists('objetivo') , undef ) ; isnt( $dtd->elem_exists('curriculo') , undef ) ; isnt( $dtd->elem_exists('disciplina') , undef ) ; isnt( $dtd->elem_exists('descricao') , undef ) ; isnt( $dtd->elem_exists('requisito') , undef ) ; isnt( $dtd->elem_exists('professor') , undef ) ; isnt( $dtd->elem_exists('br') , undef ) ; isnt( $dtd->is_elem_req('requisito') , undef ) ; isnt( $dtd->is_elem_uniq('requisito') , undef ) ; isnt( $dtd->is_elem_opt('curriculo') , undef ) ; isnt( !$dtd->is_elem_req('curriculo') , undef ) ; isnt( $dtd->is_elem_multi('professor') , undef ) ; isnt( $dtd->is_elem_pcdata('professor') , undef ) ; isnt( $dtd->is_elem_empty('br') , undef ) ; isnt( $dtd->attr_exists('curso','centro') , undef ) ; isnt( $dtd->attr_exists('curso','nome') , undef ) ; isnt( $dtd->attr_exists('curso','centro','nome') , undef ) ; is( $dtd->attr_exists('curso','centro','nomes'), undef ) ; my @attrs = $dtd->get_attrs('curso', undef ) ; cmp_ok( join(" ",@attrs), 'eq', 'centro nome age' ) ; @attrs = $dtd->get_attrs_req('curso') ; cmp_ok( join(" ",@attrs) , 'eq', 'centro nome') ; done_testing() ; } ; ######################### subtest 'Default Parser cds Tests' => sub { my $xml = XML::Smart->new()->{cds} ; $xml = $xml->copy() ; # Cannot copy object and expect previous state to remain ! $xml->{album}[0] = { title => 'foo' , artist => 'the foos' , tracks => 8 , } ; $xml->{album}[1] = { title => 'bar' , artist => 'the barss' , tracks => [qw(6 7)] , time => [qw(60 70)] , type => 'b' , } ; $xml->{album}[2] = { title => 'baz' , artist => undef , tracks => 10 , type => '' , br => 123 , } ; $xml->{creator} = 'Joe' ; $xml->{date} = '2000-01-01' ; $xml->{type} = 'a' ; $xml->{album}[0]{title}->set_node(1); cmp_ok( $xml->data( noheader=>1 , nospace=>1), 'eq', q`foo67`) ; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1), 'eq', q` ]>the foos8the barss6710
` ); done_testing() ; } ; ######################### subtest 'Default Parser apply_dtd Tests' => sub { my $xml = XML::Smart->new; $xml = $xml->copy() ; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml = $xml->copy() ; $xml->apply_dtd(q` ]> `); $xml = $xml->copy() ; cmp_ok( $xml->data(noheader=>1 , nospace=>1 , nodtd=>1), 'eq', q`555-1234` ); done_testing() ; } ; ######################### subtest 'URL Tests' => sub { eval(q`use LWP::UserAgent`) ; if ( $@ ) { plan skip_all => 'URL Tests require LWP::UserAgent' ; done_testing() ; } if( !$ENV{ URL_TESTS } ) { plan skip_all => 'Skipping URL test, Enable by setting ENV variable URL_TESTS' ; done_testing() ; } my $url = 'http://www.perlmonks.org/index.pl?node_id=16046' ; diag( "\nGetting URL... " ) ; my $XML = XML::Smart->new($url , 'XML::Smart::Parser') ; $XML = $XML->copy() ; cmp_ok( $XML->{XPINFO}{INFO}{sitename}, 'eq', 'PerlMonks' ) ; done_testing() ; } ; ######################### done_testing() ; exit() ; XML-Smart-1.78/t/force_case_bug_fix.t0000644000175000017500000000133212110211431016720 0ustar harishharish#!perl -T use 5.006 ; use strict ; use warnings FATAL => 'all' ; use Test::More ; use XML::Smart ; my @xml = ; my $xml = join( '', @xml ) ; subtest 'Force case' => sub { my $XML1 = new XML::Smart ( $xml, lowarg => 1, lowtag => 1, ); my $XML2 = new XML::Smart ( $xml, lowarg => 1, lowtag => 1, ); my $data = $XML1->tree()->{ note }{ to }{ CONTENT } ; cmp_ok( $data, 'eq', 'Tove', 'Force to downcase: bug id 17834' ); done_testing() ; }; done_testing() ; __DATA__ Tove Jani Reminder Don't forget me this weekend! XML-Smart-1.78/t/pod-coverage.t0000644000175000017500000000122312110211431015476 0ustar harishharishuse strict; use warnings; use Test::More; unless ( $ENV{RELEASE_TESTING} ) { plan( skip_all => "Author tests not required for installation" ); } # Ensure a recent version of Test::Pod::Coverage my $min_tpc = 1.08; eval "use Test::Pod::Coverage $min_tpc"; plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" if $@; # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, # but older versions don't recognize some common documentation styles my $min_pc = 0.18; eval "use Pod::Coverage $min_pc"; plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" if $@; all_pod_coverage_ok(); XML-Smart-1.78/t/boilerplate.t0000644000175000017500000000250312110211431015427 0ustar harishharish#!perl -T use 5.006; use strict; use warnings FATAL => 'all'; use Test::More; plan tests => 3; sub not_in_file_ok { my ($filename, %regex) = @_; open( my $fh, '<', $filename ) or die "couldn't open $filename for reading: $!"; my %violated; while (my $line = <$fh>) { while (my ($desc, $regex) = each %regex) { if ($line =~ $regex) { push @{$violated{$desc}||=[]}, $.; } } } if (%violated) { fail("$filename contains boilerplate text"); diag "$_ appears on lines @{$violated{$_}}" for keys %violated; } else { pass("$filename contains no boilerplate text"); } } sub module_boilerplate_ok { my ($module) = @_; not_in_file_ok($module => 'the great new $MODULENAME' => qr/ - The great new /, 'boilerplate description' => qr/Quick summary of what the module/, 'stub function definition' => qr/function[12]/, ); } TODO: { local $TODO = "Need to replace the boilerplate text"; not_in_file_ok(README => "The README is used..." => qr/The README is used/, "'version information here'" => qr/to provide version information/, ); not_in_file_ok(Changes => "placeholder date/time" => qr(Date/time) ); module_boilerplate_ok('lib/XML/Smart.pm'); } XML-Smart-1.78/t/hex.t0000644000175000017500000000170212110211431013711 0ustar harishharish#!perl -T use 5.006 ; use strict ; use warnings FATAL => 'all' ; use Test::More ; use XML::Smart ; subtest 'Raw Binary Data' => sub { my $bin_data_string = '‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ' ; my @bin_data = split( //, $bin_data_string ) ; foreach my $bin_elem ( @bin_data ) { cmp_ok( XML::Smart::_data_type( $bin_elem ), '==', 4, 'RawBinData: ' . "0x" . unpack("H*", $bin_elem ) ); } done_testing() ; }; subtest 'Raw Binary Data Unimplemented' => sub { my @bin_data = ( 0x80, 0x81, 0x8d, 0x8f, 0x90, 0xa0 ); foreach my $bin_elem ( @bin_data ) { my $bin_elem_converted = pack("H*", $bin_elem ); cmp_ok( XML::Smart::_data_type( $bin_elem ), '==', 1, 'RawBinData Unimplemented: ' . "0x" . $bin_elem ); } done_testing() ; }; done_testing() ; XML-Smart-1.78/t/copy_fail.t0000644000175000017500000000130212110211431015066 0ustar harishharish#!perl -T use 5.006 ; use strict ; use warnings FATAL => 'all' ; use Test::More ; use XML::Smart ; my @xml = ; my $xml = join( '', @xml ) ; subtest 'Copy' => sub { my $xml_ob = XML::Smart->new( $xml ) ; my $xml_ob_copy = $xml_ob->copy() ; cmp_ok( $xml_ob->nodes_keys, 'eq', $xml_ob_copy->nodes_keys, 'Basic Copy Test' ); $xml_ob = $xml_ob->{ test }; $xml_ob_copy = $xml_ob->copy() ; cmp_ok( $xml_ob->nodes_keys, 'eq', $xml_ob_copy->nodes_keys, 'Stepped Copy Test' ); done_testing() ; }; done_testing() ; __DATA__ XML-Smart-1.78/t/00-load.t0000644000175000017500000000034012110211431014256 0ustar harishharish#!perl -T use 5.006; use strict; use warnings FATAL => 'all'; use Test::More; plan tests => 1; BEGIN { use_ok( 'XML::Smart' ) || print "Bail out!\n"; } diag( "Testing XML::Smart $XML::Smart::VERSION, Perl $], $^X" ); XML-Smart-1.78/t/base_tests.t0000644000175000017500000011013412214343243015275 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test::More ; use ExtUtils::MakeMaker ; use XML::Smart ; my $DATA = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; ##if (0) { ######################### subtest 'HTML Tests' => sub { my $XML = XML::Smart->new( q` Blah blah


` ); my $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok($data, 'eq', q` Blah blah


`) ; my @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'input br input br') ; $XML->{html}{body}{form}->set_order( qw(br input input br) ) ; @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'br input input br') ; $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok( $data, 'eq', q` Blah blah


`) ; done_testing() ; } ; subtest 'Pointer Tests' => sub { my $XML = XML::Smart->new(q` content0 sub_content content1 content2 ` , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; cmp_ok($data, 'eq', q` content0 sub_content content1 content2 `) ; my $tmp = tied $XML->{root}->pointer->{CONTENT} ; isnt( tied $XML->{root}->pointer->{CONTENT}, undef ) ; my $cont = $XML->{root}->{CONTENT} ; cmp_ok($cont, 'eq', q` content0 content1 content2 `) ; my $cont_ = $XML->{root}->content ; cmp_ok( $cont_, 'eq', q` content0 content1 content2 `) ; $XML->{root}->content(1,"set1") ; my @cont = $XML->{root}->content ; cmp_ok($cont[0], 'eq', "\ncontent0\n") ; cmp_ok($cont[1], 'eq', "set1") ; cmp_ok($cont[2], 'eq', "\ncontent2\n") ; $XML->{root}->{CONTENT} = 123 ; my $cont_2 = $XML->{root}->content ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $cont_2, '==', 123) ; is( tied $XML->{root}->pointer->{CONTENT}, undef ) ; done_testing() ; } ; is( tied $XML->{root}{tag1}{sub}->pointer->{CONTENT}, undef, 'Undefined' ) ; my $sub_cont = $XML->{root}{tag1}{sub}->{CONTENT} ; cmp_ok($sub_cont, 'eq', 'sub_content') ; $data = $XML->data(noheader => 1) ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $data , 'eq', q`123 sub_content ` ) ; done_testing() ; }; done_testing() ; } ; subtest 'Content Set tests' => sub { my $xml = new XML::Smart(q` aaa bbb `) ; $xml = $xml->{root} ; $xml->{phone}->content('XXX') ; $xml->{phone}[1]->content('YYY') ; $xml->{test}->content('ZZZ') ; my $data = $xml->data(noheader => 1) ; cmp_ok($data, 'eq', q` XXX YYY ZZZ `) ; done_testing() ; } ; subtest 'Data Order Tests' => sub { my $xml = new XML::Smart(q` TEXT1 & more aaa bbb `,'html') ; my $data = $xml->data(noident=>1 , noheader => 1 , wild=>1) ; cmp_ok($data, 'eq', q` TEXT1 & more aaa bbb `) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tests' => sub { my $XML = XML::Smart->new('text1foobartext2' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//g ; cmp_ok($data, 'eq', 'text1foobartext2') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nometagen tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $data = $XML->data(nometagen => 1) ; $data =~ s/\s//gs ; my $data_org = $DATA ; $data_org =~ s/\s//gs ; cmp_ok( $data, 'eq', $data_org) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::HTMLParser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '' ) ; $XML = XML::Smart->new(q` TITLE end" w=q> FOO2-DATA ` , 'HTML') ; $data = $XML->data(noheader => 1 , nospace => 1 ) ; cmp_ok($data, 'eq', q`TITLEFOO2-DATA`) ; $XML = XML::Smart->new(q` TITLE ` , 'HTML') ; $data = $XML->data(noheader => 1 , nospace => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', q`TITLE`); done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser args Tests' => sub { my $XML = XML::Smart->new(q` <.sub1 arg="1" x=1 /> <.sub2 arg="2"/> content ` , 'XML::Smart::HTMLParser') ; my $data = $XML->data(noheader => 1 , wild => 1) ; cmp_ok( $data, 'eq', q` <.sub1 arg="1" x="1"/> <.sub2 arg="2"/> content `); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tree tests' => sub { my $XML0 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; my $XML1 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; my $XML = XML::Smart->new() ; $XML->{sub}{sub2} = $XML0->tree ; push(@{$XML->{sub}{sub2}} , $XML1->tree ) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{server}[0]{address} ; cmp_ok($addr, 'eq', '192.168.0.1') ; my $addr0 = $XML->{server}[0]{address}[0] ; cmp_ok( $addr, 'eq', $addr0); my $addr1 = $XML->{server}{address}[1] ; cmp_ok( $addr1, 'eq', '192.168.0.2') ; my $addr01 = $XML->{server}[0]{address}[1] ; cmp_ok( $addr1, 'eq', $addr01); my @addrs = @{$XML->{server}{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); @addrs = @{$XML->{server}[0]{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr, 'eq', '192.168.1.10') ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr, 'eq', $addr0) ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.1.20') ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok( $type, 'eq', 'conectiva') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok( $addr, 'eq', '192.168.2.100') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok( $addr0, 'eq', $addr) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Args Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $newsrv = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; push(@{$XML->{server}} , $newsrv) ; my $addr0 = $XML->{'server'}('type','eq','mandrake'){'address'}[0] ; cmp_ok( $addr0, 'eq', '192.168.3.201') ; $XML->{'server'}('type','eq','mandrake'){'address'}[1] = '192.168.3.202' ; my $addr1 = $XML->{'server'}('type','eq','mandrake'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.3.202') ; push(@{$XML->{'server'}('type','eq','conectiva'){'address'}} , '192.168.2.101') ; $addr1 = $XML->{'server'}('type','eq','conectiva'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; $addr1 = $XML->{'server'}[2]{'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; done_testing() ; } ; ######################### subtest 'Args regex Match Tests' => sub { my $XML = XML::Smart->new(q` ` , 'XML::Smart::Parser') ; my @users = $XML->{users}('email','=~','^jo') ; cmp_ok( $users[0]->{name}, 'eq', 'Joe X') ; cmp_ok( $users[1]->{name}, 'eq', 'JoH Y') ; done_testing() ; } ; ######################### subtest 'Default Parser Array Test' => sub { my $XML = XML::Smart->new() ; $XML->{server} = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; $XML->{server}{address}[1] = '192.168.3.202' ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.3.201
192.168.3.202
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser tags Test' => sub { my $XML = XML::Smart->new('ctab' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = qq`ctab` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser data() options tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML->{'hosts'}{'server'}('type','eq','conectiva'){'address'}[1] = '' ; my $data = $XML->data( noident => 1 , nospace => 1 , lowtag => 1 , upertag => 1 , uperarg => 1 , noheader => 1 , ) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data populate test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{data} = 'aaa' ; $XML->{var } = 10 ; $XML->{addr} = [qw(1 2 3)] ; my $data = $XML->data(length => 1 , nometagen => 1 ) ; $data =~ s/\s//gs ; my $dataok = q`123
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data Populate Array test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}{server} = { os => 'lx' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; my $srv = { os => 'lx' , type => 'red' , ver => 123 , } ; push( @{$XML->{hosts}} , {XXXXXX => 1}) ; unshift( @{$XML->{hosts}} , $srv) ; push( @{$XML->{hosts}{more}} , {YYYY => 1}) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}{server} = [ { os => 'lx' , type => 'a' , ver => '1' ,} , { os => 'lx ', type => 'b' , ver => '2' ,} , ]; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'a' ) ; my $srv0 = shift( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv0{type}, 'eq', 'a' ) ; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}[0]{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}[0]{server}[0]{type}[0], 'eq', 'b' ) ; my $srv1 = pop( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv1{type}, 'eq', 'b' ) ; my $data = $XML->data(noheader => 1 , nospace=>1) ; cmp_ok($data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser' ) ; my @types = $XML->{hosts}{server}('[@]','type') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; @types = $XML->{hosts}{server}{type}('<@') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my @srvs = $XML->{hosts}{server}('os','eq','linux') ; my @types ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva' ) ; @srvs = $XML->{hosts}{server}(['os','eq','linux'],['os','eq','bsd']) ; @types = () ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data encode test' => sub { my $wild = pack("C", 127 ) ; my $data = qq`$wild`; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{code}, 'eq', $wild ) ; $data = $XML->data() ; $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{code}, 'eq', $wild ) ; my $data2 = $XML->data() ; cmp_ok( $data, 'eq', $data2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $addr1 = $XML->{hosts}{server}{address} ; my $XML2 = $XML->cut_root ; my $addr2 = $XML2->{server}{address} ; cmp_ok( $addr1, 'eq', $addr2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Funny Char test' => sub { my $data = q` My Company & Name + x >> plus " + '... `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{root}{foo}, 'eq', q` My Company & Name + x >> plus " + '...` ) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q` My Company & Name + x >> plus " + '...` ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nodes test' => sub { my $XML = XML::Smart->new(q` cont ` , 'XML::Smart::Parser') ; my @nodes = $XML->{root}{foo}->nodes ; cmp_ok( $nodes[0]->{arg}, 'eq', 'z') ; @nodes = $XML->{root}{foo}->nodes_keys ; cmp_ok( "@nodes", 'eq', 'bar' ) ; isnt( $XML->{root}{foo}{bar}->is_node, undef ) ; my @keys = $XML->{root}{foo}('@keys') ; cmp_ok("@keys", 'eq', 'arg1 arg2 bar' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser CDATA test' => sub { my $data = qq` end]]> `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{root}{item}{data}, 'eq', q`some CDATA code end` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Hash assign through array Test' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{option}[0] = { name => "Help" , level => {from => 1 , to => 99} , } ; $XML->{menu}{option}[0]{sub}{option}[0] = { name => "Busca" , level => {from => 1 , to => 99} , } ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q``) ; done_testing() ; } ; ######################### subtest 'Default Parser integer data tests' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg1} = 123 ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg2}{subarg} = 999 ; cmp_ok($XML->{menu}{arg1}, '==', 123 ) ; cmp_ok($XML->{menu}{arg2}, '==', 456 ) ; cmp_ok($XML->{menu}{arg2}{subarg}, '==', 999 ) ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`456` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Args get Test' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg1} = [1,2,3] ; $XML->{menu}{arg2} = 4 ; my @arg1 = $XML->{menu}{arg1}('@') ; cmp_ok( $#arg1, '==', 2 ) ; my @arg2 = $XML->{menu}{arg2}('@') ; cmp_ok( $#arg2, '==', 0 ) ; my @arg3 = $XML->{menu}{arg3}('@') ; cmp_ok( $#arg3, '==', -1 ) ; done_testing() ; } ; ######################### subtest 'Default Parser set_node and set_order Tests' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg1} = 123 ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}{arg2}->set_node ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`456` ) ; $XML->{menu}{arg2}->set_node(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}->set_order('arg1' , 'arg2') ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; delete $XML->{menu}{arg2}[0] ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; done_testing() ; } ; ######################### subtest 'Default Parser XML Structure verification' => sub { my $XML = XML::Smart->new() ; $XML->{root}{foo} = "bla bla bla"; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', '1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', 'HASH' ) ; $XML->{root}{foo}->set_node(0) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', '' ) ; is( $XML->tree->{root}{'/nodes'}{foo}, undef ) ; $XML->{root}{foo}->set_cdata(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT} , 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_auto_node ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 1 ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_cdata(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', 'HASH' ) ; $XML->{root}{foo}->set_auto ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', '' ) ; isnt( exists $XML->tree->{root}{'/nodes'}{foo}, undef ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and Bin data tests' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "bla bla bla bla bla"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', ' bla bla]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'bla bla bla <tag> bla bla' ) ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok ($data, 'eq', 'YmxhIGJsYSBibGEgPHRhZz4gYmxhIGJsYQ==' ) ; done_testing() ; } ; ######################### subtest 'Default Parser Funny Chars, Hex and Bin data Test' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "

test \x03

"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; $XML->{root}{foo}->set_binary(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "<h1>test \x03\</h1>") ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA test' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "simple"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; $XML->{root}{foo}->set_cdata(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and funny chars' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "foo bar baz"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'foo bar baz]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '<words>foo bar baz</words>' ) ; done_testing() ; } ; ######################### subtest 'Default Parser' => sub { my $XML = XML::Smart->new(q` here's a test `, 'XML::Parser'); my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "here's a test") ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Path and XPath Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr->path, 'eq', '/hosts/server[1]/address' ) ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr0->path , 'eq', '/hosts/server[1]/address[0]') ; cmp_ok( $addr0->path_as_xpath , 'eq', '/hosts/server[2]/address') ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok($addr->path , 'eq', '/hosts/server[2]/address') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok($addr0->path , 'eq', '/hosts/server[2]/address[0]') ; cmp_ok($addr0->path_as_xpath , 'eq', '/hosts/server[3]/@address') ; $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; cmp_ok($type->path_as_xpath , 'eq', '/hosts/server[3]/@type') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root array Tests' => sub{ my $XML = new XML::Smart(q` 456 `,'smart'); $XML = $XML->cut_root ; my @frames_123 = @{ $XML->{'output'}('name','eq',123){'frames'} } ; my @formats_123 = map { $_->{'format'} } @frames_123 ; my @frames_456 = @{ $XML->{'output'}('name','eq',456){'frames'} } ; my @formats_456 = map { $_->{format} } @frames_456 ; cmp_ok( join(";", @formats_123) , 'eq', 'a;b' ) ; cmp_ok( join(";", @formats_456) , 'eq', 'c;d' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $html = q`

foo

`; my @tag ; my $p = XML::Smart::HTMLParser->new( Start => sub { shift; push(@tag , @_) ;}, Char => sub {}, End => sub {}, ); $p->parse($html) ; cmp_ok($tag[-1] , 'eq', '$s->{supply}->shift') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array pop Test' => sub { my $xml = new XML::Smart(q` test 1 test 2 test 3 file 1 `); $xml->{doc}{port}[0] = 0; $xml->{doc}{port}[1] = 1; $xml->{doc}{port}[2] = 2; $xml->{doc}{port}[3] = 3; my $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`test 1test 2test 3file 10123`) ; pop @{$xml->{doc}{'/order'}} ; $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`test 1test 2test 3file 10123`) ; done_testing() ; } ; ######################### subtest 'XML::XPath Tests' => sub { eval(q`use XML::XPath`) ; if( $@ ) { plan skip_all => 'XML::XPath Unavailable' ; } my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $xp1 = $XML->XPath ; my $xp2 = $XML->XPath ; cmp_ok( $xp1, 'eq', $xp2 ) ; $xp1 = $XML->XPath ; $XML->{hosts}{tmp} = 123 ; $xp2 = $XML->XPath ; ## Test cache of the XPath object: cmp_ok( $xp1, '!=', $xp2 ) ; delete $XML->{hosts}{tmp} ; my $data = $XML->XPath->findnodes_as_string('/') ; cmp_ok( $data, 'eq', q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`) ; done_testing() ; } ; ######################### subtest 'XML::Smart::DTD Tests' => sub { use XML::Smart::DTD ; my $dtd = XML::Smart::DTD->new(q` ]> `) ; isnt( $dtd->elem_exists('curso') , undef ) ; isnt( $dtd->elem_exists('objetivo') , undef ) ; isnt( $dtd->elem_exists('curriculo') , undef ) ; isnt( $dtd->elem_exists('disciplina') , undef ) ; isnt( $dtd->elem_exists('descricao') , undef ) ; isnt( $dtd->elem_exists('requisito') , undef ) ; isnt( $dtd->elem_exists('professor') , undef ) ; isnt( $dtd->elem_exists('br') , undef ) ; isnt( $dtd->is_elem_req('requisito') , undef ) ; isnt( $dtd->is_elem_uniq('requisito') , undef ) ; isnt( $dtd->is_elem_opt('curriculo') , undef ) ; isnt( !$dtd->is_elem_req('curriculo') , undef ) ; isnt( $dtd->is_elem_multi('professor') , undef ) ; isnt( $dtd->is_elem_pcdata('professor') , undef ) ; isnt( $dtd->is_elem_empty('br') , undef ) ; isnt( $dtd->attr_exists('curso','centro') , undef ) ; isnt( $dtd->attr_exists('curso','nome') , undef ) ; isnt( $dtd->attr_exists('curso','centro','nome') , undef ) ; is( $dtd->attr_exists('curso','centro','nomes'), undef ) ; my @attrs = $dtd->get_attrs('curso', undef ) ; cmp_ok( join(" ",@attrs), 'eq', 'centro nome age' ) ; @attrs = $dtd->get_attrs_req('curso') ; cmp_ok( join(" ",@attrs) , 'eq', 'centro nome') ; done_testing() ; } ; ######################### subtest 'Default Parser cds Tests' => sub { my $xml = XML::Smart->new()->{cds} ; $xml->{album}[0] = { title => 'foo' , artist => 'the foos' , tracks => 8 , } ; $xml->{album}[1] = { title => 'bar' , artist => 'the barss' , tracks => [qw(6 7)] , time => [qw(60 70)] , type => 'b' , } ; $xml->{album}[2] = { title => 'baz' , artist => undef , tracks => 10 , type => '' , br => 123 , } ; $xml->{creator} = 'Joe' ; $xml->{date} = '2000-01-01' ; $xml->{type} = 'a' ; $xml->{album}[0]{title}->set_node(1); cmp_ok( $xml->data( noheader=>1 , nospace=>1), 'eq', q`foo67`) ; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1), 'eq', q` ]>the foos8the barss6710
` ); done_testing() ; } ; ######################### subtest 'Default Parser apply_dtd Tests' => sub { my $xml = XML::Smart->new; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1 , nodtd=>1), 'eq', q`555-1234` ); done_testing() ; } ; ######################### subtest 'URL Tests' => sub { eval(q`use LWP::UserAgent`) ; if ( $@ ) { plan skip_all => 'URL Tests require LWP::UserAgent' ; done_testing() ; } if( !$ENV{ URL_TESTS } ) { plan skip_all => 'Skipping URL test, Enable by setting ENV variable URL_TESTS' ; done_testing() ; } my $url = 'http://www.perlmonks.org/index.pl?node_id=16046' ; diag( "\nGetting URL... " ) ; my $XML = XML::Smart->new($url , 'XML::Smart::Parser') ; cmp_ok( $XML->{XPINFO}{INFO}{sitename}, 'eq', 'PerlMonks' ) ; done_testing() ; } ; ######################### done_testing() ; exit() ; XML-Smart-1.78/t/obj_copy_meta.t0000644000175000017500000000101212110211431015731 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test ; use ExtUtils::MakeMaker ; BEGIN { plan tests => 1 } ; use XML::Smart ; my $xml = new XML::Smart(q` TEXT1 & more aaa bbb `,'html') ; $xml = $xml->copy() ; my $data = $xml->data(noident=>1 , noheader => 1 , wild=>1) ; ok($data,q` TEXT1 & more aaa bbb `) ; 1 ; XML-Smart-1.78/t/base_tests_for_mem_leak.t0000644000175000017500000011330112214343261017774 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test::More ; use ExtUtils::MakeMaker ; use XML::Smart ; my $DATA = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; { eval(q`use Devel::Cycle`) ; if( $@ ) { plan skip_all => 'Memory Tests require Devel::Cycle' ; done_testing() ; } } ##if (0) { ######################### subtest 'HTML Tests' => sub { my $XML = XML::Smart->new( q` Blah blah


` ); $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok($data, 'eq', q` Blah blah


`) ; my @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'input br input br') ; $XML->{html}{body}{form}->set_order( qw(br input input br) ) ; @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'br input input br') ; $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok( $data, 'eq', q` Blah blah


`) ; done_testing() ; } ; subtest 'Pointer Tests' => sub { my $XML = XML::Smart->new(q` content0 sub_content content1 content2 ` , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1) ; cmp_ok($data, 'eq', q` content0 sub_content content1 content2 `) ; my $tmp = tied $XML->{root}->pointer->{CONTENT} ; isnt( tied $XML->{root}->pointer->{CONTENT}, undef ) ; my $cont = $XML->{root}->{CONTENT} ; cmp_ok($cont, 'eq', q` content0 content1 content2 `) ; my $cont_ = $XML->{root}->content ; cmp_ok( $cont_, 'eq', q` content0 content1 content2 `) ; $XML->{root}->content(1,"set1") ; my @cont = $XML->{root}->content ; cmp_ok($cont[0], 'eq', "\ncontent0\n") ; cmp_ok($cont[1], 'eq', "set1") ; cmp_ok($cont[2], 'eq', "\ncontent2\n") ; $XML->{root}->{CONTENT} = 123 ; my $cont_2 = $XML->{root}->content ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $cont_2, '==', 123) ; is( tied $XML->{root}->pointer->{CONTENT}, undef ) ; done_testing() ; } ; is( tied $XML->{root}{tag1}{sub}->pointer->{CONTENT}, undef, 'Undefined' ) ; my $sub_cont = $XML->{root}{tag1}{sub}->{CONTENT} ; cmp_ok($sub_cont, 'eq', 'sub_content') ; $data = $XML->data(noheader => 1) ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $data , 'eq', q`123 sub_content ` ) ; done_testing() ; }; done_testing() ; } ; subtest 'Content Set tests' => sub { my $xml = new XML::Smart(q` aaa bbb `) ; $$xml->{ DEV_DEBUG } = 1 ; $xml = $xml->{root} ; $xml->{phone}->content('XXX') ; $xml->{phone}[1]->content('YYY') ; $xml->{test}->content('ZZZ') ; my $data = $xml->data(noheader => 1) ; cmp_ok($data, 'eq', q` XXX YYY ZZZ `) ; done_testing() ; } ; subtest 'Data Order Tests' => sub { my $xml = new XML::Smart(q` TEXT1 & more aaa bbb `,'html') ; $$xml->{ DEV_DEBUG } = 1 ; my $data = $xml->data(noident=>1 , noheader => 1 , wild=>1) ; cmp_ok($data, 'eq', q` TEXT1 & more aaa bbb `) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tests' => sub { my $XML = XML::Smart->new('text1foobartext2' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//g ; cmp_ok($data, 'eq', 'text1foobartext2') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nometagen tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(nometagen => 1) ; $data =~ s/\s//gs ; my $data_org = $DATA ; $data_org =~ s/\s//gs ; cmp_ok( $data, 'eq', $data_org) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::HTMLParser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '' ) ; $XML = XML::Smart->new(q` TITLE end" w=q> FOO2-DATA ` , 'HTML') ; $$XML->{ DEV_DEBUG } = 1 ; $data = $XML->data(noheader => 1 , nospace => 1 ) ; cmp_ok($data, 'eq', q`TITLEFOO2-DATA`) ; $XML = XML::Smart->new(q` TITLE ` , 'HTML') ; $$XML->{ DEV_DEBUG } = 1 ; $data = $XML->data(noheader => 1 , nospace => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', q`TITLE`); done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser args Tests' => sub { my $XML = XML::Smart->new(q` <.sub1 arg="1" x=1 /> <.sub2 arg="2"/> content ` , 'XML::Smart::HTMLParser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1 , wild => 1) ; cmp_ok( $data, 'eq', q` <.sub1 arg="1" x="1"/> <.sub2 arg="2"/> content `); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tree tests' => sub { my $XML0 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; $$XML0->{ DEV_DEBUG } = 1 ; my $XML1 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; $$XML1->{ DEV_DEBUG } = 1 ; my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{sub}{sub2} = $XML0->tree ; push(@{$XML->{sub}{sub2}} , $XML1->tree ) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML = $XML->{hosts} ; my $addr = $XML->{server}[0]{address} ; cmp_ok($addr, 'eq', '192.168.0.1') ; my $addr0 = $XML->{server}[0]{address}[0] ; cmp_ok( $addr, 'eq', $addr0); my $addr1 = $XML->{server}{address}[1] ; cmp_ok( $addr1, 'eq', '192.168.0.2') ; my $addr01 = $XML->{server}[0]{address}[1] ; cmp_ok( $addr1, 'eq', $addr01); my @addrs = @{$XML->{server}{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); @addrs = @{$XML->{server}[0]{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr, 'eq', '192.168.1.10') ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr, 'eq', $addr0) ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.1.20') ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok( $type, 'eq', 'conectiva') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok( $addr, 'eq', '192.168.2.100') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok( $addr0, 'eq', $addr) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Args Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML = $XML->{hosts} ; my $newsrv = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; push(@{$XML->{server}} , $newsrv) ; my $addr0 = $XML->{'server'}('type','eq','mandrake'){'address'}[0] ; cmp_ok( $addr0, 'eq', '192.168.3.201') ; $XML->{'server'}('type','eq','mandrake'){'address'}[1] = '192.168.3.202' ; my $addr1 = $XML->{'server'}('type','eq','mandrake'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.3.202') ; push(@{$XML->{'server'}('type','eq','conectiva'){'address'}} , '192.168.2.101') ; $addr1 = $XML->{'server'}('type','eq','conectiva'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; $addr1 = $XML->{'server'}[2]{'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; done_testing() ; } ; ######################### subtest 'Args regex Match Tests' => sub { my $XML = XML::Smart->new(q` ` , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my @users = $XML->{users}('email','=~','^jo') ; cmp_ok( $users[0]->{name}, 'eq', 'Joe X') ; cmp_ok( $users[1]->{name}, 'eq', 'JoH Y') ; done_testing() ; } ; ######################### subtest 'Default Parser Array Test' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{server} = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; $XML->{server}{address}[1] = '192.168.3.202' ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.3.201
192.168.3.202
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser tags Test' => sub { my $XML = XML::Smart->new('ctab' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = qq`ctab` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser data() options tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{'hosts'}{'server'}('type','eq','conectiva'){'address'}[1] = '' ; my $data = $XML->data( noident => 1 , nospace => 1 , lowtag => 1 , upertag => 1 , uperarg => 1 , noheader => 1 , ) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data populate test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{data} = 'aaa' ; $XML->{var } = 10 ; $XML->{addr} = [qw(1 2 3)] ; my $data = $XML->data(length => 1 , nometagen => 1 ) ; $data =~ s/\s//gs ; my $dataok = q`123
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data Populate Array test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{hosts}{server} = { os => 'lx' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $srv = { os => 'lx' , type => 'red' , ver => 123 , } ; push( @{$XML->{hosts}} , {XXXXXX => 1}) ; unshift( @{$XML->{hosts}} , $srv) ; push( @{$XML->{hosts}{more}} , {YYYY => 1}) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{hosts}{server} = [ { os => 'lx' , type => 'a' , ver => '1' ,} , { os => 'lx ', type => 'b' , ver => '2' ,} , ]; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'a' ) ; my $srv0 = shift( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv0{type}, 'eq', 'a' ) ; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}[0]{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}[0]{server}[0]{type}[0], 'eq', 'b' ) ; my $srv1 = pop( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv1{type}, 'eq', 'b' ) ; my $data = $XML->data(noheader => 1 , nospace=>1) ; cmp_ok($data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser' ) ; $$XML->{ DEV_DEBUG } = 1 ; my @types = $XML->{hosts}{server}('[@]','type') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; @types = $XML->{hosts}{server}{type}('<@') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my @srvs = $XML->{hosts}{server}('os','eq','linux') ; my @types ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva' ) ; @srvs = $XML->{hosts}{server}(['os','eq','linux'],['os','eq','bsd']) ; @types = () ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data encode test' => sub { my $wild = pack("C", 127 ) ; my $data = qq`$wild`; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; cmp_ok( $XML->{code}, 'eq', $wild ) ; $data = $XML->data() ; $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; cmp_ok( $XML->{code}, 'eq', $wild ) ; my $data2 = $XML->data() ; cmp_ok( $data, 'eq', $data2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $addr1 = $XML->{hosts}{server}{address} ; my $XML2 = $XML->cut_root ; my $addr2 = $XML2->{server}{address} ; cmp_ok( $addr1, 'eq', $addr2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Funny Char test' => sub { my $data = q` My Company & Name + x >> plus " + '... `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; cmp_ok( $XML->{root}{foo}, 'eq', q` My Company & Name + x >> plus " + '...` ) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q` My Company & Name + x >> plus " + '...` ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nodes test' => sub { my $XML = XML::Smart->new(q` cont ` , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my @nodes = $XML->{root}{foo}->nodes ; cmp_ok( $nodes[0]->{arg}, 'eq', 'z') ; @nodes = $XML->{root}{foo}->nodes_keys ; cmp_ok( "@nodes", 'eq', 'bar' ) ; isnt( $XML->{root}{foo}{bar}->is_node, undef ) ; my @keys = $XML->{root}{foo}('@keys') ; cmp_ok("@keys", 'eq', 'arg1 arg2 bar' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser CDATA test' => sub { my $data = qq` end]]> `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; cmp_ok( $XML->{root}{item}{data}, 'eq', q`some CDATA code end` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Hash assign through array Test' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{menu}{option}[0] = { name => "Help" , level => {from => 1 , to => 99} , } ; $XML->{menu}{option}[0]{sub}{option}[0] = { name => "Busca" , level => {from => 1 , to => 99} , } ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q``) ; done_testing() ; } ; ######################### subtest 'Default Parser integer data tests' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{menu}{arg1} = 123 ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg2}{subarg} = 999 ; cmp_ok($XML->{menu}{arg1}, '==', 123 ) ; cmp_ok($XML->{menu}{arg2}, '==', 456 ) ; cmp_ok($XML->{menu}{arg2}{subarg}, '==', 999 ) ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`456` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Args get Test' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{menu}{arg1} = [1,2,3] ; $XML->{menu}{arg2} = 4 ; my @arg1 = $XML->{menu}{arg1}('@') ; cmp_ok( $#arg1, '==', 2 ) ; my @arg2 = $XML->{menu}{arg2}('@') ; cmp_ok( $#arg2, '==', 0 ) ; my @arg3 = $XML->{menu}{arg3}('@') ; cmp_ok( $#arg3, '==', -1 ) ; done_testing() ; } ; ######################### subtest 'Default Parser set_node and set_order Tests' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg1} = 123 ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}{arg2}->set_node ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`456` ) ; $XML->{menu}{arg2}->set_node(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}->set_order('arg1' , 'arg2') ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; delete $XML->{menu}{arg2}[0] ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; done_testing() ; } ; ######################### subtest 'Default Parser XML Structure verification' => sub { my $XML = XML::Smart->new() ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{root}{foo} = "bla bla bla"; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', '1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', 'HASH' ) ; $XML->{root}{foo}->set_node(0) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', '' ) ; is( $XML->tree->{root}{'/nodes'}{foo}, undef ) ; $XML->{root}{foo}->set_cdata(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT} , 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_auto_node ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 1 ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_cdata(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', 'HASH' ) ; $XML->{root}{foo}->set_auto ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', '' ) ; isnt( exists $XML->tree->{root}{'/nodes'}{foo}, undef ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and Bin data tests' => sub { my $XML = new XML::Smart ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{root}{foo} = "bla bla bla bla bla"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', ' bla bla]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'bla bla bla <tag> bla bla' ) ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok ($data, 'eq', 'YmxhIGJsYSBibGEgPHRhZz4gYmxhIGJsYQ==' ) ; done_testing() ; } ; ######################### subtest 'Default Parser Funny Chars, Hex and Bin data Test' => sub { my $XML = new XML::Smart ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{root}{foo} = "

test \x03

"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; $XML->{root}{foo}->set_binary(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "<h1>test \x03\</h1>") ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA test' => sub { my $XML = new XML::Smart ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{root}{foo} = "simple"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; $XML->{root}{foo}->set_cdata(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and funny chars' => sub { my $XML = new XML::Smart ; $$XML->{ DEV_DEBUG } = 1 ; $XML->{root}{foo} = "foo bar baz"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'foo bar baz]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '<words>foo bar baz</words>' ) ; done_testing() ; } ; ######################### subtest 'Default Parser' => sub { my $XML = XML::Smart->new(q` here's a test `, 'XML::Parser'); $$XML->{ DEV_DEBUG } = 1 ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "here's a test") ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Path and XPath Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr->path, 'eq', '/hosts/server[1]/address' ) ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr0->path , 'eq', '/hosts/server[1]/address[0]') ; cmp_ok( $addr0->path_as_xpath , 'eq', '/hosts/server[2]/address') ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok($addr->path , 'eq', '/hosts/server[2]/address') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok($addr0->path , 'eq', '/hosts/server[2]/address[0]') ; cmp_ok($addr0->path_as_xpath , 'eq', '/hosts/server[3]/@address') ; $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; cmp_ok($type->path_as_xpath , 'eq', '/hosts/server[3]/@type') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root array Tests' => sub{ my $XML = new XML::Smart(q` 456 `,'smart'); $$XML->{ DEV_DEBUG } = 1 ; $XML = $XML->cut_root ; my @frames_123 = @{ $XML->{'output'}('name','eq',123){'frames'} } ; my @formats_123 = map { $_->{'format'} } @frames_123 ; my @frames_456 = @{ $XML->{'output'}('name','eq',456){'frames'} } ; my @formats_456 = map { $_->{format} } @frames_456 ; cmp_ok( join(";", @formats_123) , 'eq', 'a;b' ) ; cmp_ok( join(";", @formats_456) , 'eq', 'c;d' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $html = q`

foo

`; my @tag ; my $p = XML::Smart::HTMLParser->new( Start => sub { shift; push(@tag , @_) ;}, Char => sub {}, End => sub {}, ); $p->parse($html) ; cmp_ok($tag[-1] , 'eq', '$s->{supply}->shift') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array pop Test' => sub { my $xml = new XML::Smart(q` test 1 test 2 test 3 file 1 `); $$xml->{ DEV_DEBUG } = 1 ; $xml->{doc}{port}[0] = 0; $xml->{doc}{port}[1] = 1; $xml->{doc}{port}[2] = 2; $xml->{doc}{port}[3] = 3; my $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`test 1test 2test 3file 10123`) ; pop @{$xml->{doc}{'/order'}} ; $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`test 1test 2test 3file 10123`) ; done_testing() ; } ; ######################### subtest 'XML::XPath Tests' => sub { eval(q`use XML::XPath`) ; if( $@ ) { plan skip_all => 'XML::XPath Unavailable' ; } my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; my $xp1 = $XML->XPath ; my $xp2 = $XML->XPath ; cmp_ok( $xp1, 'eq', $xp2 ) ; $xp1 = $XML->XPath ; $XML->{hosts}{tmp} = 123 ; $xp2 = $XML->XPath ; ## Test cache of the XPath object: cmp_ok( $xp1, '!=', $xp2 ) ; delete $XML->{hosts}{tmp} ; my $data = $XML->XPath->findnodes_as_string('/') ; cmp_ok( $data, 'eq', q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`) ; done_testing() ; } ; ######################### subtest 'XML::Smart::DTD Tests' => sub { use XML::Smart::DTD ; my $dtd = XML::Smart::DTD->new(q` ]> `) ; isnt( $dtd->elem_exists('curso') , undef ) ; isnt( $dtd->elem_exists('objetivo') , undef ) ; isnt( $dtd->elem_exists('curriculo') , undef ) ; isnt( $dtd->elem_exists('disciplina') , undef ) ; isnt( $dtd->elem_exists('descricao') , undef ) ; isnt( $dtd->elem_exists('requisito') , undef ) ; isnt( $dtd->elem_exists('professor') , undef ) ; isnt( $dtd->elem_exists('br') , undef ) ; isnt( $dtd->is_elem_req('requisito') , undef ) ; isnt( $dtd->is_elem_uniq('requisito') , undef ) ; isnt( $dtd->is_elem_opt('curriculo') , undef ) ; isnt( !$dtd->is_elem_req('curriculo') , undef ) ; isnt( $dtd->is_elem_multi('professor') , undef ) ; isnt( $dtd->is_elem_pcdata('professor') , undef ) ; isnt( $dtd->is_elem_empty('br') , undef ) ; isnt( $dtd->attr_exists('curso','centro') , undef ) ; isnt( $dtd->attr_exists('curso','nome') , undef ) ; isnt( $dtd->attr_exists('curso','centro','nome') , undef ) ; is( $dtd->attr_exists('curso','centro','nomes'), undef ) ; my @attrs = $dtd->get_attrs('curso', undef ) ; cmp_ok( join(" ",@attrs), 'eq', 'centro nome age' ) ; @attrs = $dtd->get_attrs_req('curso') ; cmp_ok( join(" ",@attrs) , 'eq', 'centro nome') ; done_testing() ; } ; ######################### subtest 'Default Parser cds Tests' => sub { my $xml = XML::Smart->new()->{cds} ; $$xml->{ DEV_DEBUG } = 1 ; $xml->{album}[0] = { title => 'foo' , artist => 'the foos' , tracks => 8 , } ; $xml->{album}[1] = { title => 'bar' , artist => 'the barss' , tracks => [qw(6 7)] , time => [qw(60 70)] , type => 'b' , } ; $xml->{album}[2] = { title => 'baz' , artist => undef , tracks => 10 , type => '' , br => 123 , } ; $xml->{creator} = 'Joe' ; $xml->{date} = '2000-01-01' ; $xml->{type} = 'a' ; $xml->{album}[0]{title}->set_node(1); cmp_ok( $xml->data( noheader=>1 , nospace=>1), 'eq', q`foo67`) ; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1), 'eq', q` ]>the foos8the barss6710
` ); done_testing() ; } ; ######################### subtest 'Default Parser apply_dtd Tests' => sub { my $xml = XML::Smart->new; $$xml->{ DEV_DEBUG } = 1 ; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1 , nodtd=>1), 'eq', q`555-1234` ); done_testing() ; } ; ######################### subtest 'URL Tests' => sub { eval(q`use LWP::UserAgent`) ; if ( $@ ) { plan skip_all => 'URL Tests require LWP::UserAgent' ; done_testing() ; } if( !$ENV{ URL_TESTS } ) { plan skip_all => 'Skipping URL test, Enable by setting ENV variable URL_TESTS' ; done_testing() ; } my $url = 'http://www.perlmonks.org/index.pl?node_id=16046' ; diag( "\nGetting URL... " ) ; my $XML = XML::Smart->new($url , 'XML::Smart::Parser') ; $$XML->{ DEV_DEBUG } = 1 ; cmp_ok( $XML->{XPINFO}{INFO}{sitename}, 'eq', 'PerlMonks' ) ; done_testing() ; } ; ######################### done_testing() ; exit() ; XML-Smart-1.78/t/base_tests_multi_obj.t0000644000175000017500000011037412214343410017343 0ustar harishharishuse strict ; use warnings FATAL => 'all' ; use Test::More ; use ExtUtils::MakeMaker ; use XML::Smart ; my $DATA = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; my $XML = new XML::Smart() ; $XML = new XML::Smart() ; $XML = new XML::Smart() ; my $xml = new XML::Smart() ; $xml = new XML::Smart() ; $xml = new XML::Smart() ; ######################### subtest 'HTML Tests' => sub { my $XML = XML::Smart->new( q` Blah blah


` ); my $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok($data, 'eq', q` Blah blah


`) ; my @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'input br input br') ; $XML->{html}{body}{form}->set_order( qw(br input input br) ) ; @order = $XML->{html}{body}{form}->order ; cmp_ok( join(" ", @order), 'eq', 'br input input br') ; $data = $XML->data( noheader => 1 ) ; $data =~ s/\s+/ /gs ; cmp_ok( $data, 'eq', q` Blah blah


`) ; done_testing() ; } ; subtest 'Pointer Tests' => sub { my $XML = XML::Smart->new(q` content0 sub_content content1 content2 ` , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; cmp_ok($data, 'eq', q` content0 sub_content content1 content2 `) ; my $tmp = tied $XML->{root}->pointer->{CONTENT} ; isnt( tied $XML->{root}->pointer->{CONTENT}, undef ) ; my $cont = $XML->{root}->{CONTENT} ; cmp_ok($cont, 'eq', q` content0 content1 content2 `) ; my $cont_ = $XML->{root}->content ; cmp_ok( $cont_, 'eq', q` content0 content1 content2 `) ; $XML->{root}->content(1,"set1") ; my @cont = $XML->{root}->content ; cmp_ok($cont[0], 'eq', "\ncontent0\n") ; cmp_ok($cont[1], 'eq', "set1") ; cmp_ok($cont[2], 'eq', "\ncontent2\n") ; $XML->{root}->{CONTENT} = 123 ; my $cont_2 = $XML->{root}->content ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $cont_2, '==', 123) ; is( tied $XML->{root}->pointer->{CONTENT}, undef ) ; done_testing() ; } ; is( tied $XML->{root}{tag1}{sub}->pointer->{CONTENT}, undef, 'Undefined' ) ; my $sub_cont = $XML->{root}{tag1}{sub}->{CONTENT} ; cmp_ok($sub_cont, 'eq', 'sub_content') ; $data = $XML->data(noheader => 1) ; subtest 'Perl Version Tests' => sub { if( $] >= 5.007 && $] <= 5.008 ) { plan skip_all => "Skip on $]" ; } cmp_ok( $data , 'eq', q`123 sub_content ` ) ; done_testing() ; }; done_testing() ; } ; subtest 'Content Set tests' => sub { my $xml = new XML::Smart(q` aaa bbb `) ; $xml = $xml->{root} ; $xml->{phone}->content('XXX') ; $xml->{phone}[1]->content('YYY') ; $xml->{test}->content('ZZZ') ; my $data = $xml->data(noheader => 1) ; cmp_ok($data, 'eq', q` XXX YYY ZZZ `) ; done_testing() ; } ; subtest 'Data Order Tests' => sub { my $xml = new XML::Smart(q` TEXT1 & more aaa bbb `,'html') ; my $data = $xml->data(noident=>1 , noheader => 1 , wild=>1) ; cmp_ok($data, 'eq', q` TEXT1 & more aaa bbb `) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tests' => sub { my $XML = XML::Smart->new('text1foobartext2' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//g ; cmp_ok($data, 'eq', 'text1foobartext2') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nometagen tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $data = $XML->data(nometagen => 1) ; $data =~ s/\s//gs ; my $data_org = $DATA ; $data_org =~ s/\s//gs ; cmp_ok( $data, 'eq', $data_org) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::HTMLParser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '' ) ; $XML = XML::Smart->new(q` TITLE end" w=q> FOO2-DATA ` , 'HTML') ; $data = $XML->data(noheader => 1 , nospace => 1 ) ; cmp_ok($data, 'eq', q`TITLEFOO2-DATA`) ; $XML = XML::Smart->new(q` TITLE ` , 'HTML') ; $data = $XML->data(noheader => 1 , nospace => 1) ; $data =~ s/\s//gs ; cmp_ok($data, 'eq', q`TITLE`); done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser args Tests' => sub { my $XML = XML::Smart->new(q` <.sub1 arg="1" x=1 /> <.sub2 arg="2"/> content ` , 'XML::Smart::HTMLParser') ; my $data = $XML->data(noheader => 1 , wild => 1) ; cmp_ok( $data, 'eq', q` <.sub1 arg="1" x="1"/> <.sub2 arg="2"/> content `); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Tree tests' => sub { my $XML0 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; my $XML1 = XML::Smart->new(q`` , 'XML::Smart::Parser') ; my $XML = XML::Smart->new() ; $XML->{sub}{sub2} = $XML0->tree ; push(@{$XML->{sub}{sub2}} , $XML1->tree ) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; cmp_ok( $data, 'eq', '') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{server}[0]{address} ; cmp_ok($addr, 'eq', '192.168.0.1') ; my $addr0 = $XML->{server}[0]{address}[0] ; cmp_ok( $addr, 'eq', $addr0); my $addr1 = $XML->{server}{address}[1] ; cmp_ok( $addr1, 'eq', '192.168.0.2') ; my $addr01 = $XML->{server}[0]{address}[1] ; cmp_ok( $addr1, 'eq', $addr01); my @addrs = @{$XML->{server}{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); @addrs = @{$XML->{server}[0]{address}} ; cmp_ok( $addrs[0], 'eq', $addr0); cmp_ok( $addrs[1], 'eq', $addr1); done_testing() ; } ; ######################### subtest 'XML::Smart::Parser args Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr, 'eq', '192.168.1.10') ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr, 'eq', $addr0) ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.1.20') ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok( $type, 'eq', 'conectiva') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok( $addr, 'eq', '192.168.2.100') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok( $addr0, 'eq', $addr) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Args Array Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $newsrv = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; push(@{$XML->{server}} , $newsrv) ; my $addr0 = $XML->{'server'}('type','eq','mandrake'){'address'}[0] ; cmp_ok( $addr0, 'eq', '192.168.3.201') ; $XML->{'server'}('type','eq','mandrake'){'address'}[1] = '192.168.3.202' ; my $addr1 = $XML->{'server'}('type','eq','mandrake'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.3.202') ; push(@{$XML->{'server'}('type','eq','conectiva'){'address'}} , '192.168.2.101') ; $addr1 = $XML->{'server'}('type','eq','conectiva'){'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; $addr1 = $XML->{'server'}[2]{'address'}[1] ; cmp_ok( $addr1, 'eq', '192.168.2.101') ; done_testing() ; } ; ######################### subtest 'Args regex Match Tests' => sub { my $XML = XML::Smart->new(q` ` , 'XML::Smart::Parser') ; my @users = $XML->{users}('email','=~','^jo') ; cmp_ok( $users[0]->{name}, 'eq', 'Joe X') ; cmp_ok( $users[1]->{name}, 'eq', 'JoH Y') ; done_testing() ; } ; ######################### subtest 'Default Parser Array Test' => sub { my $XML = XML::Smart->new() ; $XML->{server} = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; $XML->{server}{address}[1] = '192.168.3.202' ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.3.201
192.168.3.202
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser tags Test' => sub { my $XML = XML::Smart->new('ctab' , 'XML::Smart::Parser') ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = qq`ctab` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser data() options tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML->{'hosts'}{'server'}('type','eq','conectiva'){'address'}[1] = '' ; my $data = $XML->data( noident => 1 , nospace => 1 , lowtag => 1 , upertag => 1 , uperarg => 1 , noheader => 1 , ) ; $data =~ s/\s//gs ; my $dataok = q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data populate test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{data} = 'aaa' ; $XML->{var } = 10 ; $XML->{addr} = [qw(1 2 3)] ; my $data = $XML->data(length => 1 , nometagen => 1 ) ; $data =~ s/\s//gs ; my $dataok = q`123
`; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data Populate Array test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}{server} = { os => 'lx' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}[1]{server}[0] = { os => 'LX' , type => 'red' , ver => 123 , } ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q``; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; my $srv = { os => 'lx' , type => 'red' , ver => 123 , } ; push( @{$XML->{hosts}} , {XXXXXX => 1}) ; unshift( @{$XML->{hosts}} , $srv) ; push( @{$XML->{hosts}{more}} , {YYYY => 1}) ; my $data = $XML->data(noheader => 1) ; $data =~ s/\s//gs ; my $dataok = q`` ; cmp_ok( $data, 'eq', $dataok ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended Hash assign test' => sub { my $XML = XML::Smart->new('' , 'XML::Smart::Parser') ; $XML->{hosts}{server} = [ { os => 'lx' , type => 'a' , ver => '1' ,} , { os => 'lx ', type => 'b' , ver => '2' ,} , ]; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'a' ) ; my $srv0 = shift( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv0{type}, 'eq', 'a' ) ; cmp_ok( $XML->{hosts}{server}{type}, 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}{server}[0]{type}[0], 'eq', 'b' ) ; cmp_ok( $XML->{hosts}[0]{server}[0]{type}[0], 'eq', 'b' ) ; my $srv1 = pop( @{$XML->{hosts}{server}} ) ; cmp_ok( $$srv1{type}, 'eq', 'b' ) ; my $data = $XML->data(noheader => 1 , nospace=>1) ; cmp_ok($data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser' ) ; my @types = $XML->{hosts}{server}('[@]','type') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; @types = $XML->{hosts}{server}{type}('<@') ; cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Extended node extraction test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my @srvs = $XML->{hosts}{server}('os','eq','linux') ; my @types ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva' ) ; @srvs = $XML->{hosts}{server}(['os','eq','linux'],['os','eq','bsd']) ; @types = () ; foreach my $srvs_i ( @srvs ) { push(@types , $srvs_i->{type}) ;} cmp_ok("@types", 'eq', 'redhat suse conectiva freebsd' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Data encode test' => sub { my $wild = pack("C", 127 ) ; my $data = qq`$wild`; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{code}, 'eq', $wild ) ; $data = $XML->data() ; $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{code}, 'eq', $wild ) ; my $data2 = $XML->data() ; cmp_ok( $data, 'eq', $data2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root test' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $addr1 = $XML->{hosts}{server}{address} ; my $XML2 = $XML->cut_root ; my $addr2 = $XML2->{server}{address} ; cmp_ok( $addr1, 'eq', $addr2 ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Funny Char test' => sub { my $data = q` My Company & Name + x >> plus " + '... `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{root}{foo}, 'eq', q` My Company & Name + x >> plus " + '...` ) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q` My Company & Name + x >> plus " + '...` ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser nodes test' => sub { my $XML = XML::Smart->new(q` cont ` , 'XML::Smart::Parser') ; my @nodes = $XML->{root}{foo}->nodes ; cmp_ok( $nodes[0]->{arg}, 'eq', 'z') ; @nodes = $XML->{root}{foo}->nodes_keys ; cmp_ok( "@nodes", 'eq', 'bar' ) ; isnt( $XML->{root}{foo}{bar}->is_node, undef ) ; my @keys = $XML->{root}{foo}('@keys') ; cmp_ok("@keys", 'eq', 'arg1 arg2 bar' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser CDATA test' => sub { my $data = qq` end]]> `; my $XML = XML::Smart->new($data , 'XML::Smart::Parser') ; cmp_ok( $XML->{root}{item}{data}, 'eq', q`some CDATA code end` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Hash assign through array Test' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{option}[0] = { name => "Help" , level => {from => 1 , to => 99} , } ; $XML->{menu}{option}[0]{sub}{option}[0] = { name => "Busca" , level => {from => 1 , to => 99} , } ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q``) ; done_testing() ; } ; ######################### subtest 'Default Parser integer data tests' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg1} = 123 ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg2}{subarg} = 999 ; cmp_ok($XML->{menu}{arg1}, '==', 123 ) ; cmp_ok($XML->{menu}{arg2}, '==', 456 ) ; cmp_ok($XML->{menu}{arg2}{subarg}, '==', 999 ) ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`456` ) ; done_testing() ; } ; ######################### subtest 'Default Parser Args get Test' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg1} = [1,2,3] ; $XML->{menu}{arg2} = 4 ; my @arg1 = $XML->{menu}{arg1}('@') ; cmp_ok( $#arg1, '==', 2 ) ; my @arg2 = $XML->{menu}{arg2}('@') ; cmp_ok( $#arg2, '==', 0 ) ; my @arg3 = $XML->{menu}{arg3}('@') ; cmp_ok( $#arg3, '==', -1 ) ; done_testing() ; } ; ######################### subtest 'Default Parser set_node and set_order Tests' => sub { my $XML = XML::Smart->new() ; $XML->{menu}{arg2} = 456 ; $XML->{menu}{arg1} = 123 ; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}{arg2}->set_node ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`456` ) ; $XML->{menu}{arg2}->set_node(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; $XML->{menu}->set_order('arg1' , 'arg2') ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; delete $XML->{menu}{arg2}[0] ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`` ) ; done_testing() ; } ; ######################### subtest 'Default Parser XML Structure verification' => sub { my $XML = XML::Smart->new() ; $XML->{root}{foo} = "bla bla bla"; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', '1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', 'HASH' ) ; $XML->{root}{foo}->set_node(0) ; cmp_ok( ref $XML->tree->{ root }{ foo }, 'eq', '' ) ; is( $XML->tree->{root}{'/nodes'}{foo}, undef ) ; $XML->{root}{foo}->set_cdata(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT} , 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_node(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(1) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,1,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_auto_node ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 1 ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_cdata(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'cdata,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; $XML->{root}{foo}->set_binary(0) ; cmp_ok( $XML->tree->{root}{'/nodes'}{foo}, 'eq', 'binary,0,1' ) ; cmp_ok( $XML->tree->{root}{foo}{CONTENT}, 'eq', "bla bla bla" ) ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', 'HASH' ) ; $XML->{root}{foo}->set_auto ; cmp_ok( ref( $XML->tree->{root}{foo} ), 'eq', '' ) ; isnt( exists $XML->tree->{root}{'/nodes'}{foo}, undef ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and Bin data tests' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "bla bla bla bla bla"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', ' bla bla]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'bla bla bla <tag> bla bla' ) ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok ($data, 'eq', 'YmxhIGJsYSBibGEgPHRhZz4gYmxhIGJsYQ==' ) ; done_testing() ; } ; ######################### subtest 'Default Parser Funny Chars, Hex and Bin data Test' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "

test \x03

"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; $XML->{root}{foo}->set_binary(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "<h1>test \x03\</h1>") ; $XML->{root}{foo}->set_binary(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'PGgxPnRlc3QgAzwvaDE+' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA test' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "simple"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; $XML->{root}{foo}->set_cdata(1) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '' ) ; done_testing() ; } ; ######################### subtest 'Default Parser CDATA and funny chars' => sub { my $XML = new XML::Smart ; $XML->{root}{foo} = "foo bar baz"; my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', 'foo bar baz]]>' ) ; $XML->{root}{foo}->set_cdata(0) ; $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', '<words>foo bar baz</words>' ) ; done_testing() ; } ; ######################### subtest 'Default Parser' => sub { my $XML = XML::Smart->new(q` here's a test `, 'XML::Parser'); my $data = $XML->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', "here's a test") ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Path and XPath Tests' => sub { my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; $XML = $XML->{hosts} ; my $addr = $XML->{'server'}('type','eq','suse'){'address'} ; cmp_ok( $addr->path, 'eq', '/hosts/server[1]/address' ) ; my $addr0 = $XML->{'server'}('type','eq','suse'){'address'}[0] ; cmp_ok( $addr0->path , 'eq', '/hosts/server[1]/address[0]') ; cmp_ok( $addr0->path_as_xpath , 'eq', '/hosts/server[2]/address') ; my $addr1 = $XML->{'server'}('type','eq','suse'){'address'}[1] ; my $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; $addr = $XML->{'server'}('version','>=','9'){'address'} ; cmp_ok($addr->path , 'eq', '/hosts/server[2]/address') ; $addr0 = $XML->{'server'}('version','>=','9'){'address'}[0] ; cmp_ok($addr0->path , 'eq', '/hosts/server[2]/address[0]') ; cmp_ok($addr0->path_as_xpath , 'eq', '/hosts/server[3]/@address') ; $type = $XML->{'server'}('version','>=','9'){'type'} ; cmp_ok($type->path , 'eq', '/hosts/server[2]/type') ; cmp_ok($type->path_as_xpath , 'eq', '/hosts/server[3]/@type') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser cut_root array Tests' => sub{ my $XML = new XML::Smart(q` 456 `,'smart'); $XML = $XML->cut_root ; my @frames_123 = @{ $XML->{'output'}('name','eq',123){'frames'} } ; my @formats_123 = map { $_->{'format'} } @frames_123 ; my @frames_456 = @{ $XML->{'output'}('name','eq',456){'frames'} } ; my @formats_456 = map { $_->{format} } @frames_456 ; cmp_ok( join(";", @formats_123) , 'eq', 'a;b' ) ; cmp_ok( join(";", @formats_456) , 'eq', 'c;d' ) ; done_testing() ; } ; ######################### subtest 'XML::Smart::HTMLParser Tests' => sub { my $html = q`

foo

`; my @tag ; my $p = XML::Smart::HTMLParser->new( Start => sub { shift; push(@tag , @_) ;}, Char => sub {}, End => sub {}, ); $p->parse($html) ; cmp_ok($tag[-1] , 'eq', '$s->{supply}->shift') ; done_testing() ; } ; ######################### subtest 'XML::Smart::Parser Array pop Test' => sub { my $xml = new XML::Smart(q` test 1 test 2 test 3 file 1 `); $xml->{doc}{port}[0] = 0; $xml->{doc}{port}[1] = 1; $xml->{doc}{port}[2] = 2; $xml->{doc}{port}[3] = 3; my $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok($data, 'eq', q`test 1test 2test 3file 10123`) ; pop @{$xml->{doc}{'/order'}} ; $data = $xml->data(nospace => 1 , noheader => 1 ) ; cmp_ok( $data, 'eq', q`test 1test 2test 3file 10123`) ; done_testing() ; } ; ######################### subtest 'XML::XPath Tests' => sub { eval(q`use XML::XPath`) ; if( $@ ) { plan skip_all => 'XML::XPath Unavailable' ; } my $XML = XML::Smart->new($DATA , 'XML::Smart::Parser') ; my $xp1 = $XML->XPath ; my $xp2 = $XML->XPath ; cmp_ok( $xp1, 'eq', $xp2 ) ; $xp1 = $XML->XPath ; $XML->{hosts}{tmp} = 123 ; $xp2 = $XML->XPath ; ## Test cache of the XPath object: cmp_ok( $xp1, '!=', $xp2 ) ; delete $XML->{hosts}{tmp} ; my $data = $XML->XPath->findnodes_as_string('/') ; cmp_ok( $data, 'eq', q`
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
`) ; done_testing() ; } ; ######################### subtest 'XML::Smart::DTD Tests' => sub { use XML::Smart::DTD ; my $dtd = XML::Smart::DTD->new(q` ]> `) ; isnt( $dtd->elem_exists('curso') , undef ) ; isnt( $dtd->elem_exists('objetivo') , undef ) ; isnt( $dtd->elem_exists('curriculo') , undef ) ; isnt( $dtd->elem_exists('disciplina') , undef ) ; isnt( $dtd->elem_exists('descricao') , undef ) ; isnt( $dtd->elem_exists('requisito') , undef ) ; isnt( $dtd->elem_exists('professor') , undef ) ; isnt( $dtd->elem_exists('br') , undef ) ; isnt( $dtd->is_elem_req('requisito') , undef ) ; isnt( $dtd->is_elem_uniq('requisito') , undef ) ; isnt( $dtd->is_elem_opt('curriculo') , undef ) ; isnt( !$dtd->is_elem_req('curriculo') , undef ) ; isnt( $dtd->is_elem_multi('professor') , undef ) ; isnt( $dtd->is_elem_pcdata('professor') , undef ) ; isnt( $dtd->is_elem_empty('br') , undef ) ; isnt( $dtd->attr_exists('curso','centro') , undef ) ; isnt( $dtd->attr_exists('curso','nome') , undef ) ; isnt( $dtd->attr_exists('curso','centro','nome') , undef ) ; is( $dtd->attr_exists('curso','centro','nomes'), undef ) ; my @attrs = $dtd->get_attrs('curso', undef ) ; cmp_ok( join(" ",@attrs), 'eq', 'centro nome age' ) ; @attrs = $dtd->get_attrs_req('curso') ; cmp_ok( join(" ",@attrs) , 'eq', 'centro nome') ; done_testing() ; } ; ######################### subtest 'Default Parser cds Tests' => sub { my $xml = XML::Smart->new()->{cds} ; $xml->{album}[0] = { title => 'foo' , artist => 'the foos' , tracks => 8 , } ; $xml->{album}[1] = { title => 'bar' , artist => 'the barss' , tracks => [qw(6 7)] , time => [qw(60 70)] , type => 'b' , } ; $xml->{album}[2] = { title => 'baz' , artist => undef , tracks => 10 , type => '' , br => 123 , } ; $xml->{creator} = 'Joe' ; $xml->{date} = '2000-01-01' ; $xml->{type} = 'a' ; $xml->{album}[0]{title}->set_node(1); cmp_ok( $xml->data( noheader=>1 , nospace=>1), 'eq', q`foo67`) ; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1), 'eq', q` ]>the foos8the barss6710
` ); done_testing() ; } ; ######################### subtest 'Default Parser apply_dtd Tests' => sub { my $xml = XML::Smart->new; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml->apply_dtd(q` ]> `); cmp_ok( $xml->data(noheader=>1 , nospace=>1 , nodtd=>1), 'eq', q`555-1234` ); done_testing() ; } ; ######################### subtest 'URL Tests' => sub { eval(q`use LWP::UserAgent`) ; if ( $@ ) { plan skip_all => 'URL Tests require LWP::UserAgent' ; done_testing() ; } if( !$ENV{ URL_TESTS } ) { plan skip_all => 'Skipping URL test, Enable by setting ENV variable URL_TESTS' ; done_testing() ; } my $url = 'http://www.perlmonks.org/index.pl?node_id=16046' ; diag( "\nGetting URL... " ) ; my $XML = XML::Smart->new($url , 'XML::Smart::Parser') ; cmp_ok( $XML->{XPINFO}{INFO}{sitename}, 'eq', 'PerlMonks' ) ; done_testing() ; } ; ######################### done_testing() ; exit() ; XML-Smart-1.78/t/manifest.t0000644000175000017500000000050712110211431014735 0ustar harishharish#!perl -T use 5.006; use strict; use warnings FATAL => 'all'; use Test::More; unless ( $ENV{RELEASE_TESTING} ) { plan( skip_all => "Author tests not required for installation" ); } my $min_tcm = 0.9; eval "use Test::CheckManifest $min_tcm"; plan skip_all => "Test::CheckManifest $min_tcm required" if $@; ok_manifest(); XML-Smart-1.78/t/pod.t0000644000175000017500000000035012110211431013705 0ustar harishharish#!perl -T use strict; use warnings; use Test::More; # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok(); XML-Smart-1.78/Makefile.PL0000644000175000017500000000134612214353115014466 0ustar harishharishuse 5.006 ; use strict ; use warnings FATAL => 'all' ; use ExtUtils::MakeMaker ; WriteMakefile( NAME => 'XML::Smart' , AUTHOR => q{Graciliano M. P. } , VERSION_FROM => 'lib/XML/Smart.pm' , ABSTRACT_FROM => 'lib/XML/Smart.pm' , PL_FILES => {}, MIN_PERL_VERSION => 5.006 , CONFIGURE_REQUIRES => { 'ExtUtils::MakeMaker' => 0 , }, BUILD_REQUIRES => { 'Test::More' => 0 , }, PREREQ_PM => { 'Object::MultiType' => 0.03 , }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Blah-*' }, LICENSE => 'perl' ); XML-Smart-1.78/README0000644000175000017500000000522712103722141013372 0ustar harishharishXML::SMART XML::Smart - A smart, easy and powerful way to access or create XML from files, data and URLs. DESCRIPTION This module provides an easy way to access/create XML data. It's based on a HASH tree created from the XML data, and enables dynamic access to it through the standard Perl syntax for Hash and Array, without necessarily caring about which you are working with. In other words, B! This module additionally provides special resources such as: search for nodes by attribute, select an attribute value in each multiple node, change the returned format, and so on. The module also automatically handles binary data (encoding/decoding to/from base64), CDATA (like contents with ) and Unicode. It can be used to create XML files, load XML from the Web ( just by using an URL as the file path ) and has an easy way to send XML data through sockets - just adding the length of the data in the header. You can use I with L, or with the 2 standart parsers of XML::Smart: XML::Smart::Parser XML::Smart::HTMLParser INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES Object::MultiType 0.3 -> I made this module specially for XML::Smart, but can be used in others too ;-P. XML::Parser (OPTIONAL) TODO * Finish XPath implementation. * DTD. * Implement a better way to declare meta tags. AUTHOR Graciliano M. P. C<< >> I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P CURRENT MAINTAINER Harish Madabushi, C<< >> SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc XML::Smart You can also look for information at: RT, CPAN's request tracker (report bugs here) http://rt.cpan.org/NoAuth/Bugs.html?Dist=XML-Smart AnnoCPAN, Annotated CPAN documentation http://annocpan.org/dist/XML-Smart CPAN Ratings http://cpanratings.perl.org/d/XML-Smart Search CPAN http://search.cpan.org/dist/XML-Smart/ GitHub CPAN https://github.com/harishmadabushi/XML-Smart XML::Smart::Tutorial ( Tutorial and examples for XML::Smart. ) XML::Smart::FAQ ( XML::Smart Frequently Asked Questions. ) LICENSE AND COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. XML-Smart-1.78/data_for_tests/0000755000175000017500000000000012214355545015522 5ustar harishharishXML-Smart-1.78/data_for_tests/Tamil.data0000644000175000017500000000010012101730313017373 0ustar harishharish௦௧௨௩௪௫௬௭௮௯௰௱௲௳௴௵௶௷௸௹௺ XML-Smart-1.78/data_for_tests/Spanish.data0000644000175000017500000000012612101730313017742 0ustar harishharishLos árboles no dejan ver el bosque Nadie está contento con su suerte balcón jabón XML-Smart-1.78/data_for_tests/Random.data0000644000175000017500000041312112101730313017560 0ustar harishharishChar Code Char Code Char Code Char Code Char Code Char Code Char Code Char Code 160 ¡ 161 ¢ 162 £ 163 ¤ 164 Â¥ 165 ¦ 166 § 167 ¨ 168 © 169 ª 170 « 171 ¬ 172 173 ® 174 ¯ 175 ° 176 ± 177 ² 178 ³ 179 ´ 180 µ 181 ¶ 182 · 183 ¸ 184 ¹ 185 º 186 » 187 ¼ 188 ½ 189 ¾ 190 ¿ 191 À 192 - 193  194 à 195 Ä 196 Ã… 197 Æ 198 Ç 199 È 200 É 201 Ê 202 Ë 203 ÃŒ 204 à 205 ÃŽ 206 à 207 à 208 Ñ 209 Ã’ 210 Ó 211 Ô 212 Õ 213 Ö 214 × 215 Ø 216 Ù 217 Ú 218 Û 219 Ü 220 à 221 Þ 222 ß 223 à 224 á 225 â 226 ã 227 ä 228 Ã¥ 229 æ 230 ç 231 è 232 é 233 ê 234 ë 235 ì 236 í 237 î 238 ï 239 ð 240 ñ 241 ò 242 ó 243 ô 244 õ 245 ö 246 ÷ 247 ø 248 ù 249 ú 250 û 251 ü 252 ý 253 þ 254 ÿ 255 Ä€ 100 Ä 110 Ę 118 Ķ 136 Ń 143 Ó d3 Åš 15a Ű 170 Ä 101 Ä‘ 111 Ä™ 119 Ä· 137 Å„ 144 ó f3 Å› 15b ű 171 Ä‚ 102 ÄŽ 10e Äš 11a Ĺ 139; Å… 145 Å’ 152 Å  160 Ų 172 ă 103 Ä 10f Ä› 11b ĺ 13a ņ 146 Å“ 153 Å¡ 161 ų 173 Ä„ 104 Ä’ 112 Ä» 13b Ň 147 Å• 155 Å¢ 162 Ÿ 178 Ä… 105 Ä“ 113 Ä¢ 122 ļ 13c ň 148 Å– 156 Å£ 163 Ź 179 Ć 106 Ä• 115 Ä£ 123 Ľ 13d ÅŒ 14c Å— 157 ź 17a ć 107 Ä– 116 Ī 12a ľ 13e Å 14d Ř 158 Å¥ 165 Å» 17b ÄŒ 10c Ä— 117 Ä« 12b Å 150 Å™ 159 ż 17c Ä 10d Ä® 12e Å 141 Å‘ 151 Åž 15e Ž 17d į 12f Å‚ 142 ÅŸ 15f ž 17e Њ CYRILLIC CAPITAL LETTER NJE (U+040A) d08a Ћ CYRILLIC CAPITAL LETTER TSHE (U+040B) d08b ÐŒ CYRILLIC CAPITAL LETTER KJE (U+040C) d08c Ð CYRILLIC CAPITAL LETTER I WITH GRAVE (U+040D) d08d ÐŽ CYRILLIC CAPITAL LETTER SHORT U (U+040E) d08e Ð CYRILLIC CAPITAL LETTER DZHE (U+040F) d08f Ð CYRILLIC CAPITAL LETTER A (U+0410) d090 Б CYRILLIC CAPITAL LETTER BE (U+0411) d091 Ð’ CYRILLIC CAPITAL LETTER VE (U+0412) d092 Г CYRILLIC CAPITAL LETTER GHE (U+0413) d093 Д CYRILLIC CAPITAL LETTER DE (U+0414) d094 Е CYRILLIC CAPITAL LETTER IE (U+0415) d095 Ж CYRILLIC CAPITAL LETTER ZHE (U+0416) d096 З CYRILLIC CAPITAL LETTER ZE (U+0417) d097 И CYRILLIC CAPITAL LETTER I (U+0418) d098 Й CYRILLIC CAPITAL LETTER SHORT I (U+0419) d099 К CYRILLIC CAPITAL LETTER KA (U+041A) d09a Л CYRILLIC CAPITAL LETTER EL (U+041B) d09b М CYRILLIC CAPITAL LETTER EM (U+041C) d09c Ð CYRILLIC CAPITAL LETTER EN (U+041D) d09d О CYRILLIC CAPITAL LETTER O (U+041E) d09e П CYRILLIC CAPITAL LETTER PE (U+041F) d09f Р CYRILLIC CAPITAL LETTER ER (U+0420) d0a0 С CYRILLIC CAPITAL LETTER ES (U+0421) d0a1 Т CYRILLIC CAPITAL LETTER TE (U+0422) d0a2 У CYRILLIC CAPITAL LETTER U (U+0423) d0a3 Ф CYRILLIC CAPITAL LETTER EF (U+0424) d0a4 Ð¥ CYRILLIC CAPITAL LETTER HA (U+0425) d0a5 Ц CYRILLIC CAPITAL LETTER TSE (U+0426) d0a6 Ч CYRILLIC CAPITAL LETTER CHE (U+0427) d0a7 Ш CYRILLIC CAPITAL LETTER SHA (U+0428) d0a8 Щ CYRILLIC CAPITAL LETTER SHCHA (U+0429) d0a9 Ъ CYRILLIC CAPITAL LETTER HARD SIGN (U+042A) d0aa Ы CYRILLIC CAPITAL LETTER YERU (U+042B) d0ab Ь CYRILLIC CAPITAL LETTER SOFT SIGN (U+042C) d0ac Э CYRILLIC CAPITAL LETTER E (U+042D) d0ad Ю CYRILLIC CAPITAL LETTER YU (U+042E) d0ae Я CYRILLIC CAPITAL LETTER YA (U+042F) d0af а CYRILLIC SMALL LETTER A (U+0430) d0b0 б CYRILLIC SMALL LETTER BE (U+0431) d0b1 в CYRILLIC SMALL LETTER VE (U+0432) d0b2 г CYRILLIC SMALL LETTER GHE (U+0433) d0b3 д CYRILLIC SMALL LETTER DE (U+0434) d0b4 е CYRILLIC SMALL LETTER IE (U+0435) d0b5 ж CYRILLIC SMALL LETTER ZHE (U+0436) d0b6 з CYRILLIC SMALL LETTER ZE (U+0437) d0b7 и CYRILLIC SMALL LETTER I (U+0438) d0b8 й CYRILLIC SMALL LETTER SHORT I (U+0439) d0b9 к CYRILLIC SMALL LETTER KA (U+043A) d0ba л CYRILLIC SMALL LETTER EL (U+043B) d0bb м CYRILLIC SMALL LETTER EM (U+043C) d0bc н CYRILLIC SMALL LETTER EN (U+043D) d0bd о CYRILLIC SMALL LETTER O (U+043E) d0be п CYRILLIC SMALL LETTER PE (U+043F) d0bf Ñ€ CYRILLIC SMALL LETTER ER (U+0440) d180 Ñ CYRILLIC SMALL LETTER ES (U+0441) d181 Ñ‚ CYRILLIC SMALL LETTER TE (U+0442) d182 у CYRILLIC SMALL LETTER U (U+0443) d183 Ñ„ CYRILLIC SMALL LETTER EF (U+0444) d184 Ñ… CYRILLIC SMALL LETTER HA (U+0445) d185 ц CYRILLIC SMALL LETTER TSE (U+0446) d186 ч CYRILLIC SMALL LETTER CHE (U+0447) d187 ш CYRILLIC SMALL LETTER SHA (U+0448) d188 щ CYRILLIC SMALL LETTER SHCHA (U+0449) d189 ÑŠ CYRILLIC SMALL LETTER HARD SIGN (U+044A) d18a Ñ‹ CYRILLIC SMALL LETTER YERU (U+044B) d18b ÑŒ CYRILLIC SMALL LETTER SOFT SIGN (U+044C) d18c Ñ CYRILLIC SMALL LETTER E (U+044D) d18d ÑŽ CYRILLIC SMALL LETTER YU (U+044E) d18e Ñ CYRILLIC SMALL LETTER YA (U+044F) d18f Ñ CYRILLIC SMALL LETTER IE WITH GRAVE (U+0450) d190 Ñ‘ CYRILLIC SMALL LETTER IO (U+0451) d191 Ñ’ CYRILLIC SMALL LETTER DJE (U+0452) d192 Ñ“ CYRILLIC SMALL LETTER GJE (U+0453) d193 Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE (U+0454) d194 Ñ• CYRILLIC SMALL LETTER DZE (U+0455) d195 Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I (U+0456) d196 Ñ— CYRILLIC SMALL LETTER YI (U+0457) d197 ј CYRILLIC SMALL LETTER JE (U+0458) d198 Ñ™ CYRILLIC SMALL LETTER LJE (U+0459) d199 Ñš CYRILLIC SMALL LETTER NJE (U+045A) d19a Ñ› CYRILLIC SMALL LETTER TSHE (U+045B) d19b Ñœ CYRILLIC SMALL LETTER KJE (U+045C) d19c Ñ CYRILLIC SMALL LETTER I WITH GRAVE (U+045D) d19d Ñž CYRILLIC SMALL LETTER SHORT U (U+045E) d19e ÑŸ CYRILLIC SMALL LETTER DZHE (U+045F) d19f Ñ  CYRILLIC CAPITAL LETTER OMEGA (U+0460) d1a0 Ñ¡ CYRILLIC SMALL LETTER OMEGA (U+0461) d1a1 Ñ¢ CYRILLIC CAPITAL LETTER YAT (U+0462) d1a2 Ñ£ CYRILLIC SMALL LETTER YAT (U+0463) d1a3 Ѥ CYRILLIC CAPITAL LETTER IOTIFIED E (U+0464) d1a4 Ñ¥ CYRILLIC SMALL LETTER IOTIFIED E (U+0465) d1a5 Ѧ CYRILLIC CAPITAL LETTER LITTLE YUS (U+0466) d1a6 ѧ CYRILLIC SMALL LETTER LITTLE YUS (U+0467) d1a7 Ѩ CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS (U+0468) d1a8 Ñ© CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS (U+0469) d1a9 Ѫ CYRILLIC CAPITAL LETTER BIG YUS (U+046A) d1aa Ñ« CYRILLIC SMALL LETTER BIG YUS (U+046B) d1ab Ѭ CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS (U+046C) d1ac Ñ­ CYRILLIC SMALL LETTER IOTIFIED BIG YUS (U+046D) d1ad Ñ® CYRILLIC CAPITAL LETTER KSI (U+046E) d1ae ѯ CYRILLIC SMALL LETTER KSI (U+046F) d1af Ѱ CYRILLIC CAPITAL LETTER PSI (U+0470) d1b0 ѱ CYRILLIC SMALL LETTER PSI (U+0471) d1b1 Ѳ CYRILLIC CAPITAL LETTER FITA (U+0472) d1b2 ѳ CYRILLIC SMALL LETTER FITA (U+0473) d1b3 Ñ´ CYRILLIC CAPITAL LETTER IZHITSA (U+0474) d1b4 ѵ CYRILLIC SMALL LETTER IZHITSA (U+0475) d1b5 Ѷ CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (U+0476) d1b6 Ñ· CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (U+0477) d1b7 Ѹ CYRILLIC CAPITAL LETTER UK (U+0478) d1b8 ѹ CYRILLIC SMALL LETTER UK (U+0479) d1b9 Ѻ CYRILLIC CAPITAL LETTER ROUND OMEGA (U+047A) d1ba Ñ» CYRILLIC SMALL LETTER ROUND OMEGA (U+047B) d1bb Ѽ CYRILLIC CAPITAL LETTER OMEGA WITH TITLO (U+047C) d1bc ѽ CYRILLIC SMALL LETTER OMEGA WITH TITLO (U+047D) d1bd Ѿ CYRILLIC CAPITAL LETTER OT (U+047E) d1be Ñ¿ CYRILLIC SMALL LETTER OT (U+047F) d1bf Ò€ CYRILLIC CAPITAL LETTER KOPPA (U+0480) d280 Ò CYRILLIC SMALL LETTER KOPPA (U+0481) d281 Ò‚ CYRILLIC THOUSANDS SIGN (U+0482) d282 Òƒ COMBINING CYRILLIC TITLO (U+0483) d283 Ò„ COMBINING CYRILLIC PALATALIZATION (U+0484) d284 Ò… COMBINING CYRILLIC DASIA PNEUMATA (U+0485) d285 Ò† COMBINING CYRILLIC PSILI PNEUMATA (U+0486) d286 Ò‡ COMBINING CYRILLIC POKRYTIE (U+0487) d287 Òˆ COMBINING CYRILLIC HUNDRED THOUSANDS SIGN (U+0488) d288 Ò‰ COMBINING CYRILLIC MILLIONS SIGN (U+0489) d289 ÒŠ CYRILLIC CAPITAL LETTER SHORT I WITH TAIL (U+048A) d28a Ò‹ CYRILLIC SMALL LETTER SHORT I WITH TAIL (U+048B) d28b ÒŒ CYRILLIC CAPITAL LETTER SEMISOFT SIGN (U+048C) d28c Ò CYRILLIC SMALL LETTER SEMISOFT SIGN (U+048D) d28d ÒŽ CYRILLIC CAPITAL LETTER ER WITH TICK (U+048E) d28e Ò CYRILLIC SMALL LETTER ER WITH TICK (U+048F) d28f Ò CYRILLIC CAPITAL LETTER GHE WITH UPTURN (U+0490) d290 Ò‘ CYRILLIC SMALL LETTER GHE WITH UPTURN (U+0491) d291 Ò’ CYRILLIC CAPITAL LETTER GHE WITH STROKE (U+0492) d292 Ò“ CYRILLIC SMALL LETTER GHE WITH STROKE (U+0493) d293 Ò” CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK (U+0494) d294 Ò• CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK (U+0495) d295 Ò– CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER (U+0496) d296 Ò— CYRILLIC SMALL LETTER ZHE WITH DESCENDER (U+0497) d297 Ò˜ CYRILLIC CAPITAL LETTER ZE WITH DESCENDER (U+0498) d298 Ò™ CYRILLIC SMALL LETTER ZE WITH DESCENDER (U+0499) d299 Òš CYRILLIC CAPITAL LETTER KA WITH DESCENDER (U+049A) d29a Ò› CYRILLIC SMALL LETTER KA WITH DESCENDER (U+049B) d29b Òœ CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE (U+049C) d29c Ò CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE (U+049D) d29d Òž CYRILLIC CAPITAL LETTER KA WITH STROKE (U+049E) d29e ÒŸ CYRILLIC SMALL LETTER KA WITH STROKE (U+049F) d29f Ò  CYRILLIC CAPITAL LETTER BASHKIR KA (U+04A0) d2a0 Ò¡ CYRILLIC SMALL LETTER BASHKIR KA (U+04A1) d2a1 Ò¢ CYRILLIC CAPITAL LETTER EN WITH DESCENDER (U+04A2) d2a2 Ò£ CYRILLIC SMALL LETTER EN WITH DESCENDER (U+04A3) d2a3 Ò¤ CYRILLIC CAPITAL LIGATURE EN GHE (U+04A4) d2a4 Ò¥ CYRILLIC SMALL LIGATURE EN GHE (U+04A5) d2a5 Ò¦ CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK (U+04A6) d2a6 Ò§ CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK (U+04A7) d2a7 Ò¨ CYRILLIC CAPITAL LETTER ABKHASIAN HA (U+04A8) d2a8 Ò© CYRILLIC SMALL LETTER ABKHASIAN HA (U+04A9) d2a9 Òª CYRILLIC CAPITAL LETTER ES WITH DESCENDER (U+04AA) d2aa Ò« CYRILLIC SMALL LETTER ES WITH DESCENDER (U+04AB) d2ab Ò¬ CYRILLIC CAPITAL LETTER TE WITH DESCENDER (U+04AC) d2ac Ò­ CYRILLIC SMALL LETTER TE WITH DESCENDER (U+04AD) d2ad Ò® CYRILLIC CAPITAL LETTER STRAIGHT U (U+04AE) d2ae Ò¯ CYRILLIC SMALL LETTER STRAIGHT U (U+04AF) d2af Ò° CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE (U+04B0) d2b0 Ò± CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE (U+04B1) d2b1 Ò² CYRILLIC CAPITAL LETTER HA WITH DESCENDER (U+04B2) d2b2 Ò³ CYRILLIC SMALL LETTER HA WITH DESCENDER (U+04B3) d2b3 Ò´ CYRILLIC CAPITAL LIGATURE TE TSE (U+04B4) d2b4 Òµ CYRILLIC SMALL LIGATURE TE TSE (U+04B5) d2b5 Ò¶ CYRILLIC CAPITAL LETTER CHE WITH DESCENDER (U+04B6) d2b6 Ò· CYRILLIC SMALL LETTER CHE WITH DESCENDER (U+04B7) d2b7 Ò¸ CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE (U+04B8) d2b8 Ò¹ CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE (U+04B9) d2b9 Òº CYRILLIC CAPITAL LETTER SHHA (U+04BA) d2ba Ò» CYRILLIC SMALL LETTER SHHA (U+04BB) d2bb Ò¼ CYRILLIC CAPITAL LETTER ABKHASIAN CHE (U+04BC) d2bc Ò½ CYRILLIC SMALL LETTER ABKHASIAN CHE (U+04BD) d2bd Ò¾ CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER (U+04BE) d2be Ò¿ CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER (U+04BF) d2bf Ó€ CYRILLIC LETTER PALOCHKA (U+04C0) d380 Ó CYRILLIC CAPITAL LETTER ZHE WITH BREVE (U+04C1) d381 Ó‚ CYRILLIC SMALL LETTER ZHE WITH BREVE (U+04C2) d382 Óƒ CYRILLIC CAPITAL LETTER KA WITH HOOK (U+04C3) d383 Ó„ CYRILLIC SMALL LETTER KA WITH HOOK (U+04C4) d384 Ó… CYRILLIC CAPITAL LETTER EL WITH TAIL (U+04C5) d385 Ó† CYRILLIC SMALL LETTER EL WITH TAIL (U+04C6) d386 Ó‡ CYRILLIC CAPITAL LETTER EN WITH HOOK (U+04C7) d387 Óˆ CYRILLIC SMALL LETTER EN WITH HOOK (U+04C8) d388 Ó‰ CYRILLIC CAPITAL LETTER EN WITH TAIL (U+04C9) d389 ÓŠ CYRILLIC SMALL LETTER EN WITH TAIL (U+04CA) d38a Ó‹ CYRILLIC CAPITAL LETTER KHAKASSIAN CHE (U+04CB) d38b ÓŒ CYRILLIC SMALL LETTER KHAKASSIAN CHE (U+04CC) d38c Ó CYRILLIC CAPITAL LETTER EM WITH TAIL (U+04CD) d38d ÓŽ CYRILLIC SMALL LETTER EM WITH TAIL (U+04CE) d38e Ó CYRILLIC SMALL LETTER PALOCHKA (U+04CF) d38f Ó CYRILLIC CAPITAL LETTER A WITH BREVE (U+04D0) d390 Ó‘ CYRILLIC SMALL LETTER A WITH BREVE (U+04D1) d391 Ó’ CYRILLIC CAPITAL LETTER A WITH DIAERESIS (U+04D2) d392 Ó“ CYRILLIC SMALL LETTER A WITH DIAERESIS (U+04D3) d393 Ó” CYRILLIC CAPITAL LIGATURE A IE (U+04D4) d394 Ó• CYRILLIC SMALL LIGATURE A IE (U+04D5) d395 Ó– CYRILLIC CAPITAL LETTER IE WITH BREVE (U+04D6) d396 Ó— CYRILLIC SMALL LETTER IE WITH BREVE (U+04D7) d397 Ó˜ CYRILLIC CAPITAL LETTER SCHWA (U+04D8) d398 Ó™ CYRILLIC SMALL LETTER SCHWA (U+04D9) d399 Óš CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS (U+04DA) d39a Ó› CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS (U+04DB) d39b Óœ CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS (U+04DC) d39c Ó CYRILLIC SMALL LETTER ZHE WITH DIAERESIS (U+04DD) d39d Óž CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS (U+04DE) d39e ÓŸ CYRILLIC SMALL LETTER ZE WITH DIAERESIS (U+04DF) d39f Ó  CYRILLIC CAPITAL LETTER ABKHASIAN DZE (U+04E0) d3a0 Ó¡ CYRILLIC SMALL LETTER ABKHASIAN DZE (U+04E1) d3a1 Ó¢ CYRILLIC CAPITAL LETTER I WITH MACRON (U+04E2) d3a2 Ó£ CYRILLIC SMALL LETTER I WITH MACRON (U+04E3) d3a3 Ó¤ CYRILLIC CAPITAL LETTER I WITH DIAERESIS (U+04E4) d3a4 Ó¥ CYRILLIC SMALL LETTER I WITH DIAERESIS (U+04E5) d3a5 Ó¦ CYRILLIC CAPITAL LETTER O WITH DIAERESIS (U+04E6) d3a6 Ó§ CYRILLIC SMALL LETTER O WITH DIAERESIS (U+04E7) d3a7 Ó¨ CYRILLIC CAPITAL LETTER BARRED O (U+04E8) d3a8 Ó© CYRILLIC SMALL LETTER BARRED O (U+04E9) d3a9 Óª CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS (U+04EA) d3aa Ó« CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS (U+04EB) d3ab Ó¬ CYRILLIC CAPITAL LETTER E WITH DIAERESIS (U+04EC) d3ac Ó­ CYRILLIC SMALL LETTER E WITH DIAERESIS (U+04ED) d3ad Ó® CYRILLIC CAPITAL LETTER U WITH MACRON (U+04EE) d3ae Ó¯ CYRILLIC SMALL LETTER U WITH MACRON (U+04EF) d3af Ó° CYRILLIC CAPITAL LETTER U WITH DIAERESIS (U+04F0) d3b0 Ó± CYRILLIC SMALL LETTER U WITH DIAERESIS (U+04F1) d3b1 Ó² CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE (U+04F2) d3b2 Ó³ CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE (U+04F3) d3b3 Ó´ CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS (U+04F4) d3b4 Óµ CYRILLIC SMALL LETTER CHE WITH DIAERESIS (U+04F5) d3b5 Ó¶ CYRILLIC CAPITAL LETTER GHE WITH DESCENDER (U+04F6) d3b6 Ó· CYRILLIC SMALL LETTER GHE WITH DESCENDER (U+04F7) d3b7 Ó¸ CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS (U+04F8) d3b8 Ó¹ CYRILLIC SMALL LETTER YERU WITH DIAERESIS (U+04F9) d3b9 Óº CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK (U+04FA) d3ba Ó» CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK (U+04FB) d3bb Ó¼ CYRILLIC CAPITAL LETTER HA WITH HOOK (U+04FC) d3bc Ó½ CYRILLIC SMALL LETTER HA WITH HOOK (U+04FD) d3bd Ó¾ CYRILLIC CAPITAL LETTER HA WITH STROKE (U+04FE) d3be Ó¿ CYRILLIC SMALL LETTER HA WITH STROKE (U+04FF) d3bf Ô€ CYRILLIC CAPITAL LETTER KOMI DE (U+0500) d480 Ô CYRILLIC SMALL LETTER KOMI DE (U+0501) d481 Ô‚ CYRILLIC CAPITAL LETTER KOMI DJE (U+0502) d482 Ôƒ CYRILLIC SMALL LETTER KOMI DJE (U+0503) d483 Ô„ CYRILLIC CAPITAL LETTER KOMI ZJE (U+0504) d484 Ô… CYRILLIC SMALL LETTER KOMI ZJE (U+0505) d485 Ô† CYRILLIC CAPITAL LETTER KOMI DZJE (U+0506) d486 Ô‡ CYRILLIC SMALL LETTER KOMI DZJE (U+0507) d487 Ôˆ CYRILLIC CAPITAL LETTER KOMI LJE (U+0508) d488 Ô‰ CYRILLIC SMALL LETTER KOMI LJE (U+0509) d489 ÔŠ CYRILLIC CAPITAL LETTER KOMI NJE (U+050A) d48a Ô‹ CYRILLIC SMALL LETTER KOMI NJE (U+050B) d48b ÔŒ CYRILLIC CAPITAL LETTER KOMI SJE (U+050C) d48c Ô CYRILLIC SMALL LETTER KOMI SJE (U+050D) d48d ÔŽ CYRILLIC CAPITAL LETTER KOMI TJE (U+050E) d48e Ô CYRILLIC SMALL LETTER KOMI TJE (U+050F) d48f Ô CYRILLIC CAPITAL LETTER REVERSED ZE (U+0510) d490 Ô‘ CYRILLIC SMALL LETTER REVERSED ZE (U+0511) d491 Ô’ CYRILLIC CAPITAL LETTER EL WITH HOOK (U+0512) d492 Ô“ CYRILLIC SMALL LETTER EL WITH HOOK (U+0513) d493 Ô” CYRILLIC CAPITAL LETTER LHA (U+0514) d494 Ô• CYRILLIC SMALL LETTER LHA (U+0515) d495 Ô– CYRILLIC CAPITAL LETTER RHA (U+0516) d496 Ô— CYRILLIC SMALL LETTER RHA (U+0517) d497 Ô˜ CYRILLIC CAPITAL LETTER YAE (U+0518) d498 Ô™ CYRILLIC SMALL LETTER YAE (U+0519) d499 Ôš CYRILLIC CAPITAL LETTER QA (U+051A) d49a Ô› CYRILLIC SMALL LETTER QA (U+051B) d49b Ôœ CYRILLIC CAPITAL LETTER WE (U+051C) d49c Ô CYRILLIC SMALL LETTER WE (U+051D) d49d Ôž CYRILLIC CAPITAL LETTER ALEUT KA (U+051E) d49e ÔŸ CYRILLIC SMALL LETTER ALEUT KA (U+051F) d49f Ô  CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK (U+0520) d4a0 Ô¡ CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK (U+0521) d4a1 Ô¢ CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK (U+0522) d4a2 Ô£ CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK (U+0523) d4a3 Ô¤ CYRILLIC CAPITAL LETTER PE WITH DESCENDER (U+0524) d4a4 Ô¥ CYRILLIC SMALL LETTER PE WITH DESCENDER (U+0525) d4a5 Ô¦ CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER (U+0526) d4a6 Ô§ CYRILLIC SMALL LETTER SHHA WITH DESCENDER (U+0527) d4a7 Ô± ARMENIAN CAPITAL LETTER AYB (U+0531) d4b1 Ô² ARMENIAN CAPITAL LETTER BEN (U+0532) d4b2 Ô³ ARMENIAN CAPITAL LETTER GIM (U+0533) d4b3 Ô´ ARMENIAN CAPITAL LETTER DA (U+0534) d4b4 Ôµ ARMENIAN CAPITAL LETTER ECH (U+0535) d4b5 Ô¶ ARMENIAN CAPITAL LETTER ZA (U+0536) d4b6 Ô· ARMENIAN CAPITAL LETTER EH (U+0537) d4b7 Ô¸ ARMENIAN CAPITAL LETTER ET (U+0538) d4b8 Ô¹ ARMENIAN CAPITAL LETTER TO (U+0539) d4b9 Ôº ARMENIAN CAPITAL LETTER ZHE (U+053A) d4ba Ô» ARMENIAN CAPITAL LETTER INI (U+053B) d4bb Ô¼ ARMENIAN CAPITAL LETTER LIWN (U+053C) d4bc Ô½ ARMENIAN CAPITAL LETTER XEH (U+053D) d4bd Ô¾ ARMENIAN CAPITAL LETTER CA (U+053E) d4be Ô¿ ARMENIAN CAPITAL LETTER KEN (U+053F) d4bf Õ€ ARMENIAN CAPITAL LETTER HO (U+0540) d580 Õ ARMENIAN CAPITAL LETTER JA (U+0541) d581 Õ‚ ARMENIAN CAPITAL LETTER GHAD (U+0542) d582 Õƒ ARMENIAN CAPITAL LETTER CHEH (U+0543) d583 Õ„ ARMENIAN CAPITAL LETTER MEN (U+0544) d584 Õ… ARMENIAN CAPITAL LETTER YI (U+0545) d585 Õ† ARMENIAN CAPITAL LETTER NOW (U+0546) d586 Õ‡ ARMENIAN CAPITAL LETTER SHA (U+0547) d587 Õˆ ARMENIAN CAPITAL LETTER VO (U+0548) d588 Õ‰ ARMENIAN CAPITAL LETTER CHA (U+0549) d589 ÕŠ ARMENIAN CAPITAL LETTER PEH (U+054A) d58a Õ‹ ARMENIAN CAPITAL LETTER JHEH (U+054B) d58b ÕŒ ARMENIAN CAPITAL LETTER RA (U+054C) d58c Õ ARMENIAN CAPITAL LETTER SEH (U+054D) d58d ÕŽ ARMENIAN CAPITAL LETTER VEW (U+054E) d58e Õ ARMENIAN CAPITAL LETTER TIWN (U+054F) d58f Õ ARMENIAN CAPITAL LETTER REH (U+0550) d590 Õ‘ ARMENIAN CAPITAL LETTER CO (U+0551) d591 Õ’ ARMENIAN CAPITAL LETTER YIWN (U+0552) d592 Õ“ ARMENIAN CAPITAL LETTER PIWR (U+0553) d593 Õ” ARMENIAN CAPITAL LETTER KEH (U+0554) d594 Õ• ARMENIAN CAPITAL LETTER OH (U+0555) d595 Õ– ARMENIAN CAPITAL LETTER FEH (U+0556) d596 Õ™ ARMENIAN MODIFIER LETTER LEFT HALF RING (U+0559) d599 Õš ARMENIAN APOSTROPHE (U+055A) d59a Õ› ARMENIAN EMPHASIS MARK (U+055B) d59b Õœ ARMENIAN EXCLAMATION MARK (U+055C) d59c Õ ARMENIAN COMMA (U+055D) d59d Õž ARMENIAN QUESTION MARK (U+055E) d59e ÕŸ ARMENIAN ABBREVIATION MARK (U+055F) d59f Õ¡ ARMENIAN SMALL LETTER AYB (U+0561) d5a1 Õ¢ ARMENIAN SMALL LETTER BEN (U+0562) d5a2 Õ£ ARMENIAN SMALL LETTER GIM (U+0563) d5a3 Õ¤ ARMENIAN SMALL LETTER DA (U+0564) d5a4 Õ¥ ARMENIAN SMALL LETTER ECH (U+0565) d5a5 Õ¦ ARMENIAN SMALL LETTER ZA (U+0566) d5a6 Õ§ ARMENIAN SMALL LETTER EH (U+0567) d5a7 Õ¨ ARMENIAN SMALL LETTER ET (U+0568) d5a8 Õ© ARMENIAN SMALL LETTER TO (U+0569) d5a9 Õª ARMENIAN SMALL LETTER ZHE (U+056A) d5aa Õ« ARMENIAN SMALL LETTER INI (U+056B) d5ab Õ¬ ARMENIAN SMALL LETTER LIWN (U+056C) d5ac Õ­ ARMENIAN SMALL LETTER XEH (U+056D) d5ad Õ® ARMENIAN SMALL LETTER CA (U+056E) d5ae Õ¯ ARMENIAN SMALL LETTER KEN (U+056F) d5af Õ° ARMENIAN SMALL LETTER HO (U+0570) d5b0 Õ± ARMENIAN SMALL LETTER JA (U+0571) d5b1 Õ² ARMENIAN SMALL LETTER GHAD (U+0572) d5b2 Õ³ ARMENIAN SMALL LETTER CHEH (U+0573) d5b3 Õ´ ARMENIAN SMALL LETTER MEN (U+0574) d5b4 Õµ ARMENIAN SMALL LETTER YI (U+0575) d5b5 Õ¶ ARMENIAN SMALL LETTER NOW (U+0576) d5b6 Õ· ARMENIAN SMALL LETTER SHA (U+0577) d5b7 Õ¸ ARMENIAN SMALL LETTER VO (U+0578) d5b8 Õ¹ ARMENIAN SMALL LETTER CHA (U+0579) d5b9 Õº ARMENIAN SMALL LETTER PEH (U+057A) d5ba Õ» ARMENIAN SMALL LETTER JHEH (U+057B) d5bb Õ¼ ARMENIAN SMALL LETTER RA (U+057C) d5bc Õ½ ARMENIAN SMALL LETTER SEH (U+057D) d5bd Õ¾ ARMENIAN SMALL LETTER VEW (U+057E) d5be Õ¿ ARMENIAN SMALL LETTER TIWN (U+057F) d5bf Ö€ ARMENIAN SMALL LETTER REH (U+0580) d680 Ö ARMENIAN SMALL LETTER CO (U+0581) d681 Ö‚ ARMENIAN SMALL LETTER YIWN (U+0582) d682 Öƒ ARMENIAN SMALL LETTER PIWR (U+0583) d683 Ö„ ARMENIAN SMALL LETTER KEH (U+0584) d684 Ö… ARMENIAN SMALL LETTER OH (U+0585) d685 Ö† ARMENIAN SMALL LETTER FEH (U+0586) d686 Ö‡ ARMENIAN SMALL LIGATURE ECH YIWN (U+0587) d687 Ö‰ ARMENIAN FULL STOP (U+0589) d689 ÖŠ ARMENIAN HYPHEN (U+058A) d68a Ö‘ HEBREW ACCENT ETNAHTA (U+0591) d691 Ö’ HEBREW ACCENT SEGOL (U+0592) d692 Ö“ HEBREW ACCENT SHALSHELET (U+0593) d693 Ö” HEBREW ACCENT ZAQEF QATAN (U+0594) d694 Ö• HEBREW ACCENT ZAQEF GADOL (U+0595) d695 Ö– HEBREW ACCENT TIPEHA (U+0596) d696 Ö— HEBREW ACCENT REVIA (U+0597) d697 Ö˜ HEBREW ACCENT ZARQA (U+0598) d698 Ö™ HEBREW ACCENT PASHTA (U+0599) d699 Öš HEBREW ACCENT YETIV (U+059A) d69a Ö› HEBREW ACCENT TEVIR (U+059B) d69b Öœ HEBREW ACCENT GERESH (U+059C) d69c Ö HEBREW ACCENT GERESH MUQDAM (U+059D) d69d Öž HEBREW ACCENT GERSHAYIM (U+059E) d69e ÖŸ HEBREW ACCENT QARNEY PARA (U+059F) d69f Ö  HEBREW ACCENT TELISHA GEDOLA (U+05A0) d6a0 Ö¡ HEBREW ACCENT PAZER (U+05A1) d6a1 Ö¢ HEBREW ACCENT ATNAH HAFUKH (U+05A2) d6a2 Ö£ HEBREW ACCENT MUNAH (U+05A3) d6a3 Ö¤ HEBREW ACCENT MAHAPAKH (U+05A4) d6a4 Ö¥ HEBREW ACCENT MERKHA (U+05A5) d6a5 Ö¦ HEBREW ACCENT MERKHA KEFULA (U+05A6) d6a6 Ö§ HEBREW ACCENT DARGA (U+05A7) d6a7 Ö¨ HEBREW ACCENT QADMA (U+05A8) d6a8 Ö© HEBREW ACCENT TELISHA QETANA (U+05A9) d6a9 Öª HEBREW ACCENT YERAH BEN YOMO (U+05AA) d6aa Ö« HEBREW ACCENT OLE (U+05AB) d6ab Ö¬ HEBREW ACCENT ILUY (U+05AC) d6ac Ö­ HEBREW ACCENT DEHI (U+05AD) d6ad Ö® HEBREW ACCENT ZINOR (U+05AE) d6ae Ö¯ HEBREW MARK MASORA CIRCLE (U+05AF) d6af Ö° HEBREW POINT SHEVA (U+05B0) d6b0 Ö± HEBREW POINT HATAF SEGOL (U+05B1) d6b1 Ö² HEBREW POINT HATAF PATAH (U+05B2) d6b2 Ö³ HEBREW POINT HATAF QAMATS (U+05B3) d6b3 Ö´ HEBREW POINT HIRIQ (U+05B4) d6b4 Öµ HEBREW POINT TSERE (U+05B5) d6b5 Ö¶ HEBREW POINT SEGOL (U+05B6) d6b6 Ö· HEBREW POINT PATAH (U+05B7) d6b7 Ö¸ HEBREW POINT QAMATS (U+05B8) d6b8 Ö¹ HEBREW POINT HOLAM (U+05B9) d6b9 Öº HEBREW POINT HOLAM HASER FOR VAV (U+05BA) d6ba Ö» HEBREW POINT QUBUTS (U+05BB) d6bb Ö¼ HEBREW POINT DAGESH OR MAPIQ (U+05BC) d6bc Ö½ HEBREW POINT METEG (U+05BD) d6bd Ö¾ HEBREW PUNCTUATION MAQAF (U+05BE) d6be Ö¿ HEBREW POINT RAFE (U+05BF) d6bf ×€ HEBREW PUNCTUATION PASEQ (U+05C0) d780 × HEBREW POINT SHIN DOT (U+05C1) d781 ׂ HEBREW POINT SIN DOT (U+05C2) d782 ׃ HEBREW PUNCTUATION SOF PASUQ (U+05C3) d783 ׄ HEBREW MARK UPPER DOT (U+05C4) d784 ×… HEBREW MARK LOWER DOT (U+05C5) d785 ׆ HEBREW PUNCTUATION NUN HAFUKHA (U+05C6) d786 ׇ HEBREW POINT QAMATS QATAN (U+05C7) d787 × HEBREW LETTER ALEF (U+05D0) d790 ב HEBREW LETTER BET (U+05D1) d791 ×’ HEBREW LETTER GIMEL (U+05D2) d792 ד HEBREW LETTER DALET (U+05D3) d793 ×” HEBREW LETTER HE (U+05D4) d794 ו HEBREW LETTER VAV (U+05D5) d795 ×– HEBREW LETTER ZAYIN (U+05D6) d796 ×— HEBREW LETTER HET (U+05D7) d797 ט HEBREW LETTER TET (U+05D8) d798 ×™ HEBREW LETTER YOD (U+05D9) d799 ך HEBREW LETTER FINAL KAF (U+05DA) d79a ×› HEBREW LETTER KAF (U+05DB) d79b ל HEBREW LETTER LAMED (U+05DC) d79c × HEBREW LETTER FINAL MEM (U+05DD) d79d מ HEBREW LETTER MEM (U+05DE) d79e ן HEBREW LETTER FINAL NUN (U+05DF) d79f ×  HEBREW LETTER NUN (U+05E0) d7a0 ס HEBREW LETTER SAMEKH (U+05E1) d7a1 ×¢ HEBREW LETTER AYIN (U+05E2) d7a2 ×£ HEBREW LETTER FINAL PE (U+05E3) d7a3 פ HEBREW LETTER PE (U+05E4) d7a4 ×¥ HEBREW LETTER FINAL TSADI (U+05E5) d7a5 צ HEBREW LETTER TSADI (U+05E6) d7a6 ×§ HEBREW LETTER QOF (U+05E7) d7a7 ר HEBREW LETTER RESH (U+05E8) d7a8 ש HEBREW LETTER SHIN (U+05E9) d7a9 ת HEBREW LETTER TAV (U+05EA) d7aa ×° HEBREW LIGATURE YIDDISH DOUBLE VAV (U+05F0) d7b0 ×± HEBREW LIGATURE YIDDISH VAV YOD (U+05F1) d7b1 ײ HEBREW LIGATURE YIDDISH DOUBLE YOD (U+05F2) d7b2 ׳ HEBREW PUNCTUATION GERESH (U+05F3) d7b3 ×´ HEBREW PUNCTUATION GERSHAYIM (U+05F4) d7b4 Ø€ ARABIC NUMBER SIGN (U+0600) d880 Ø ARABIC SIGN SANAH (U+0601) d881 Ø‚ ARABIC FOOTNOTE MARKER (U+0602) d882 ؃ ARABIC SIGN SAFHA (U+0603) d883 ؆ ARABIC-INDIC CUBE ROOT (U+0606) d886 ؇ ARABIC-INDIC FOURTH ROOT (U+0607) d887 ؈ ARABIC RAY (U+0608) d888 ؉ ARABIC-INDIC PER MILLE SIGN (U+0609) d889 ØŠ ARABIC-INDIC PER TEN THOUSAND SIGN (U+060A) d88a Ø‹ AFGHANI SIGN (U+060B) d88b ØŒ ARABIC COMMA (U+060C) d88c Ø ARABIC DATE SEPARATOR (U+060D) d88d ØŽ ARABIC POETIC VERSE SIGN (U+060E) d88e Ø ARABIC SIGN MISRA (U+060F) d88f Ø ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM (U+0610) d890 Ø‘ ARABIC SIGN ALAYHE ASSALLAM (U+0611) d891 Ø’ ARABIC SIGN RAHMATULLAH ALAYHE (U+0612) d892 Ø“ ARABIC SIGN RADI ALLAHOU ANHU (U+0613) d893 Ø” ARABIC SIGN TAKHALLUS (U+0614) d894 Ø• ARABIC SMALL HIGH TAH (U+0615) d895 Ø– ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH (U+0616) d896 Ø— ARABIC SMALL HIGH ZAIN (U+0617) d897 ؘ ARABIC SMALL FATHA (U+0618) d898 Ø™ ARABIC SMALL DAMMA (U+0619) d899 Øš ARABIC SMALL KASRA (U+061A) d89a Ø› ARABIC SEMICOLON (U+061B) d89b Øž ARABIC TRIPLE DOT PUNCTUATION MARK (U+061E) d89e ØŸ ARABIC QUESTION MARK (U+061F) d89f Ø  ARABIC LETTER KASHMIRI YEH (U+0620) d8a0 Ø¡ ARABIC LETTER HAMZA (U+0621) d8a1 Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE (U+0622) d8a2 Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE (U+0623) d8a3 ؤ ARABIC LETTER WAW WITH HAMZA ABOVE (U+0624) d8a4 Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW (U+0625) d8a5 ئ ARABIC LETTER YEH WITH HAMZA ABOVE (U+0626) d8a6 ا ARABIC LETTER ALEF (U+0627) d8a7 ب ARABIC LETTER BEH (U+0628) d8a8 Ø© ARABIC LETTER TEH MARBUTA (U+0629) d8a9 ت ARABIC LETTER TEH (U+062A) d8aa Ø« ARABIC LETTER THEH (U+062B) d8ab ج ARABIC LETTER JEEM (U+062C) d8ac Ø­ ARABIC LETTER HAH (U+062D) d8ad Ø® ARABIC LETTER KHAH (U+062E) d8ae د ARABIC LETTER DAL (U+062F) d8af ذ ARABIC LETTER THAL (U+0630) d8b0 ر ARABIC LETTER REH (U+0631) d8b1 ز ARABIC LETTER ZAIN (U+0632) d8b2 س ARABIC LETTER SEEN (U+0633) d8b3 Ø´ ARABIC LETTER SHEEN (U+0634) d8b4 ص ARABIC LETTER SAD (U+0635) d8b5 ض ARABIC LETTER DAD (U+0636) d8b6 Ø· ARABIC LETTER TAH (U+0637) d8b7 ظ ARABIC LETTER ZAH (U+0638) d8b8 ع ARABIC LETTER AIN (U+0639) d8b9 غ ARABIC LETTER GHAIN (U+063A) d8ba Ø» ARABIC LETTER KEHEH WITH TWO DOTS ABOVE (U+063B) d8bb ؼ ARABIC LETTER KEHEH WITH THREE DOTS BELOW (U+063C) d8bc ؽ ARABIC LETTER FARSI YEH WITH INVERTED V (U+063D) d8bd ؾ ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE (U+063E) d8be Ø¿ ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE (U+063F) d8bf Ù€ ARABIC TATWEEL (U+0640) d980 Ù ARABIC LETTER FEH (U+0641) d981 Ù‚ ARABIC LETTER QAF (U+0642) d982 Ùƒ ARABIC LETTER KAF (U+0643) d983 Ù„ ARABIC LETTER LAM (U+0644) d984 Ù… ARABIC LETTER MEEM (U+0645) d985 Ù† ARABIC LETTER NOON (U+0646) d986 Ù‡ ARABIC LETTER HEH (U+0647) d987 Ùˆ ARABIC LETTER WAW (U+0648) d988 Ù‰ ARABIC LETTER ALEF MAKSURA (U+0649) d989 ÙŠ ARABIC LETTER YEH (U+064A) d98a Ù‹ ARABIC FATHATAN (U+064B) d98b ÙŒ ARABIC DAMMATAN (U+064C) d98c Ù ARABIC KASRATAN (U+064D) d98d ÙŽ ARABIC FATHA (U+064E) d98e Ù ARABIC DAMMA (U+064F) d98f Ù ARABIC KASRA (U+0650) d990 Ù‘ ARABIC SHADDA (U+0651) d991 Ù’ ARABIC SUKUN (U+0652) d992 Ù“ ARABIC MADDAH ABOVE (U+0653) d993 Ù” ARABIC HAMZA ABOVE (U+0654) d994 Ù• ARABIC HAMZA BELOW (U+0655) d995 Ù– ARABIC SUBSCRIPT ALEF (U+0656) d996 Ù— ARABIC INVERTED DAMMA (U+0657) d997 Ù˜ ARABIC MARK NOON GHUNNA (U+0658) d998 Ù™ ARABIC ZWARAKAY (U+0659) d999 Ùš ARABIC VOWEL SIGN SMALL V ABOVE (U+065A) d99a Ù› ARABIC VOWEL SIGN INVERTED SMALL V ABOVE (U+065B) d99b Ùœ ARABIC VOWEL SIGN DOT BELOW (U+065C) d99c Ù ARABIC REVERSED DAMMA (U+065D) d99d Ùž ARABIC FATHA WITH TWO DOTS (U+065E) d99e ÙŸ ARABIC WAVY HAMZA BELOW (U+065F) d99f Ù  ARABIC-INDIC DIGIT ZERO (U+0660) d9a0 Ù¡ ARABIC-INDIC DIGIT ONE (U+0661) d9a1 Ù¢ ARABIC-INDIC DIGIT TWO (U+0662) d9a2 Ù£ ARABIC-INDIC DIGIT THREE (U+0663) d9a3 Ù¤ ARABIC-INDIC DIGIT FOUR (U+0664) d9a4 Ù¥ ARABIC-INDIC DIGIT FIVE (U+0665) d9a5 Ù¦ ARABIC-INDIC DIGIT SIX (U+0666) d9a6 Ù§ ARABIC-INDIC DIGIT SEVEN (U+0667) d9a7 Ù¨ ARABIC-INDIC DIGIT EIGHT (U+0668) d9a8 Ù© ARABIC-INDIC DIGIT NINE (U+0669) d9a9 Ùª ARABIC PERCENT SIGN (U+066A) d9aa Ù« ARABIC DECIMAL SEPARATOR (U+066B) d9ab Ù¬ ARABIC THOUSANDS SEPARATOR (U+066C) d9ac Ù­ ARABIC FIVE POINTED STAR (U+066D) d9ad Ù® ARABIC LETTER DOTLESS BEH (U+066E) d9ae Ù¯ ARABIC LETTER DOTLESS QAF (U+066F) d9af Ù° ARABIC LETTER SUPERSCRIPT ALEF (U+0670) d9b0 Ù± ARABIC LETTER ALEF WASLA (U+0671) d9b1 Ù² ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE (U+0672) d9b2 Ù³ ARABIC LETTER ALEF WITH WAVY HAMZA BELOW (U+0673) d9b3 Ù´ ARABIC LETTER HIGH HAMZA (U+0674) d9b4 Ùµ ARABIC LETTER HIGH HAMZA ALEF (U+0675) d9b5 Ù¶ ARABIC LETTER HIGH HAMZA WAW (U+0676) d9b6 Ù· ARABIC LETTER U WITH HAMZA ABOVE (U+0677) d9b7 Ù¸ ARABIC LETTER HIGH HAMZA YEH (U+0678) d9b8 Ù¹ ARABIC LETTER TTEH (U+0679) d9b9 Ùº ARABIC LETTER TTEHEH (U+067A) d9ba Ù» ARABIC LETTER BEEH (U+067B) d9bb Ù¼ ARABIC LETTER TEH WITH RING (U+067C) d9bc Ù½ ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS (U+067D) d9bd Ù¾ ARABIC LETTER PEH (U+067E) d9be Ù¿ ARABIC LETTER TEHEH (U+067F) d9bf Ú€ ARABIC LETTER BEHEH (U+0680) da80 Ú ARABIC LETTER HAH WITH HAMZA ABOVE (U+0681) da81 Ú‚ ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE (U+0682) da82 Úƒ ARABIC LETTER NYEH (U+0683) da83 Ú„ ARABIC LETTER DYEH (U+0684) da84 Ú… ARABIC LETTER HAH WITH THREE DOTS ABOVE (U+0685) da85 Ú† ARABIC LETTER TCHEH (U+0686) da86 Ú‡ ARABIC LETTER TCHEHEH (U+0687) da87 Úˆ ARABIC LETTER DDAL (U+0688) da88 Ú‰ ARABIC LETTER DAL WITH RING (U+0689) da89 ÚŠ ARABIC LETTER DAL WITH DOT BELOW (U+068A) da8a Ú‹ ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH (U+068B) da8b ÚŒ ARABIC LETTER DAHAL (U+068C) da8c Ú ARABIC LETTER DDAHAL (U+068D) da8d ÚŽ ARABIC LETTER DUL (U+068E) da8e Ú ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS (U+068F) da8f Ú ARABIC LETTER DAL WITH FOUR DOTS ABOVE (U+0690) da90 Ú‘ ARABIC LETTER RREH (U+0691) da91 Ú’ ARABIC LETTER REH WITH SMALL V (U+0692) da92 Ú“ ARABIC LETTER REH WITH RING (U+0693) da93 Ú” ARABIC LETTER REH WITH DOT BELOW (U+0694) da94 Ú• ARABIC LETTER REH WITH SMALL V BELOW (U+0695) da95 Ú– ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE (U+0696) da96 Ú— ARABIC LETTER REH WITH TWO DOTS ABOVE (U+0697) da97 Ú˜ ARABIC LETTER JEH (U+0698) da98 Ú™ ARABIC LETTER REH WITH FOUR DOTS ABOVE (U+0699) da99 Úš ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE (U+069A) da9a Ú› ARABIC LETTER SEEN WITH THREE DOTS BELOW (U+069B) da9b Úœ ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE (U+069C) da9c Ú ARABIC LETTER SAD WITH TWO DOTS BELOW (U+069D) da9d Úž ARABIC LETTER SAD WITH THREE DOTS ABOVE (U+069E) da9e ÚŸ ARABIC LETTER TAH WITH THREE DOTS ABOVE (U+069F) da9f Ú  ARABIC LETTER AIN WITH THREE DOTS ABOVE (U+06A0) daa0 Ú¡ ARABIC LETTER DOTLESS FEH (U+06A1) daa1 Ú¢ ARABIC LETTER FEH WITH DOT MOVED BELOW (U+06A2) daa2 Ú£ ARABIC LETTER FEH WITH DOT BELOW (U+06A3) daa3 Ú¤ ARABIC LETTER VEH (U+06A4) daa4 Ú¥ ARABIC LETTER FEH WITH THREE DOTS BELOW (U+06A5) daa5 Ú¦ ARABIC LETTER PEHEH (U+06A6) daa6 Ú§ ARABIC LETTER QAF WITH DOT ABOVE (U+06A7) daa7 Ú¨ ARABIC LETTER QAF WITH THREE DOTS ABOVE (U+06A8) daa8 Ú© ARABIC LETTER KEHEH (U+06A9) daa9 Úª ARABIC LETTER SWASH KAF (U+06AA) daaa Ú« ARABIC LETTER KAF WITH RING (U+06AB) daab Ú¬ ARABIC LETTER KAF WITH DOT ABOVE (U+06AC) daac Ú­ ARABIC LETTER NG (U+06AD) daad Ú® ARABIC LETTER KAF WITH THREE DOTS BELOW (U+06AE) daae Ú¯ ARABIC LETTER GAF (U+06AF) daaf Ú° ARABIC LETTER GAF WITH RING (U+06B0) dab0 Ú± ARABIC LETTER NGOEH (U+06B1) dab1 Ú² ARABIC LETTER GAF WITH TWO DOTS BELOW (U+06B2) dab2 Ú³ ARABIC LETTER GUEH (U+06B3) dab3 Ú´ ARABIC LETTER GAF WITH THREE DOTS ABOVE (U+06B4) dab4 Úµ ARABIC LETTER LAM WITH SMALL V (U+06B5) dab5 Ú¶ ARABIC LETTER LAM WITH DOT ABOVE (U+06B6) dab6 Ú· ARABIC LETTER LAM WITH THREE DOTS ABOVE (U+06B7) dab7 Ú¸ ARABIC LETTER LAM WITH THREE DOTS BELOW (U+06B8) dab8 Ú¹ ARABIC LETTER NOON WITH DOT BELOW (U+06B9) dab9 Úº ARABIC LETTER NOON GHUNNA (U+06BA) daba Ú» ARABIC LETTER RNOON (U+06BB) dabb Ú¼ ARABIC LETTER NOON WITH RING (U+06BC) dabc Ú½ ARABIC LETTER NOON WITH THREE DOTS ABOVE (U+06BD) dabd Ú¾ ARABIC LETTER HEH DOACHASHMEE (U+06BE) dabe Ú¿ ARABIC LETTER TCHEH WITH DOT ABOVE (U+06BF) dabf Û€ ARABIC LETTER HEH WITH YEH ABOVE (U+06C0) db80 Û ARABIC LETTER HEH GOAL (U+06C1) db81 Û‚ ARABIC LETTER HEH GOAL WITH HAMZA ABOVE (U+06C2) db82 Ûƒ ARABIC LETTER TEH MARBUTA GOAL (U+06C3) db83 Û„ ARABIC LETTER WAW WITH RING (U+06C4) db84 Û… ARABIC LETTER KIRGHIZ OE (U+06C5) db85 Û† ARABIC LETTER OE (U+06C6) db86 Û‡ ARABIC LETTER U (U+06C7) db87 Ûˆ ARABIC LETTER YU (U+06C8) db88 Û‰ ARABIC LETTER KIRGHIZ YU (U+06C9) db89 ÛŠ ARABIC LETTER WAW WITH TWO DOTS ABOVE (U+06CA) db8a Û‹ ARABIC LETTER VE (U+06CB) db8b ÛŒ ARABIC LETTER FARSI YEH (U+06CC) db8c Û ARABIC LETTER YEH WITH TAIL (U+06CD) db8d ÛŽ ARABIC LETTER YEH WITH SMALL V (U+06CE) db8e Û ARABIC LETTER WAW WITH DOT ABOVE (U+06CF) db8f Û ARABIC LETTER E (U+06D0) db90 Û‘ ARABIC LETTER YEH WITH THREE DOTS BELOW (U+06D1) db91 Û’ ARABIC LETTER YEH BARREE (U+06D2) db92 Û“ ARABIC LETTER YEH BARREE WITH HAMZA ABOVE (U+06D3) db93 Û” ARABIC FULL STOP (U+06D4) db94 Û• ARABIC LETTER AE (U+06D5) db95 Û– ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA (U+06D6) db96 Û— ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA (U+06D7) db97 Û˜ ARABIC SMALL HIGH MEEM INITIAL FORM (U+06D8) db98 Û™ ARABIC SMALL HIGH LAM ALEF (U+06D9) db99 Ûš ARABIC SMALL HIGH JEEM (U+06DA) db9a Û› ARABIC SMALL HIGH THREE DOTS (U+06DB) db9b Ûœ ARABIC SMALL HIGH SEEN (U+06DC) db9c Û ARABIC END OF AYAH (U+06DD) db9d Ûž ARABIC START OF RUB EL HIZB (U+06DE) db9e ÛŸ ARABIC SMALL HIGH ROUNDED ZERO (U+06DF) db9f Û  ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO (U+06E0) dba0 Û¡ ARABIC SMALL HIGH DOTLESS HEAD OF KHAH (U+06E1) dba1 Û¢ ARABIC SMALL HIGH MEEM ISOLATED FORM (U+06E2) dba2 Û£ ARABIC SMALL LOW SEEN (U+06E3) dba3 Û¤ ARABIC SMALL HIGH MADDA (U+06E4) dba4 Û¥ ARABIC SMALL WAW (U+06E5) dba5 Û¦ ARABIC SMALL YEH (U+06E6) dba6 Û§ ARABIC SMALL HIGH YEH (U+06E7) dba7 Û¨ ARABIC SMALL HIGH NOON (U+06E8) dba8 Û© ARABIC PLACE OF SAJDAH (U+06E9) dba9 Ûª ARABIC EMPTY CENTRE LOW STOP (U+06EA) dbaa Û« ARABIC EMPTY CENTRE HIGH STOP (U+06EB) dbab Û¬ ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE (U+06EC) dbac Û­ ARABIC SMALL LOW MEEM (U+06ED) dbad Û® ARABIC LETTER DAL WITH INVERTED V (U+06EE) dbae Û¯ ARABIC LETTER REH WITH INVERTED V (U+06EF) dbaf Û° EXTENDED ARABIC-INDIC DIGIT ZERO (U+06F0) dbb0 Û± EXTENDED ARABIC-INDIC DIGIT ONE (U+06F1) dbb1 Û² EXTENDED ARABIC-INDIC DIGIT TWO (U+06F2) dbb2 Û³ EXTENDED ARABIC-INDIC DIGIT THREE (U+06F3) dbb3 Û´ EXTENDED ARABIC-INDIC DIGIT FOUR (U+06F4) dbb4 Ûµ EXTENDED ARABIC-INDIC DIGIT FIVE (U+06F5) dbb5 Û¶ EXTENDED ARABIC-INDIC DIGIT SIX (U+06F6) dbb6 Û· EXTENDED ARABIC-INDIC DIGIT SEVEN (U+06F7) dbb7 Û¸ EXTENDED ARABIC-INDIC DIGIT EIGHT (U+06F8) dbb8 Û¹ EXTENDED ARABIC-INDIC DIGIT NINE (U+06F9) dbb9 Ûº ARABIC LETTER SHEEN WITH DOT BELOW (U+06FA) dbba Û» ARABIC LETTER DAD WITH DOT BELOW (U+06FB) dbbb Û¼ ARABIC LETTER GHAIN WITH DOT BELOW (U+06FC) dbbc Û½ ARABIC SIGN SINDHI AMPERSAND (U+06FD) dbbd Û¾ ARABIC SIGN SINDHI POSTPOSITION MEN (U+06FE) dbbe Û¿ ARABIC LETTER HEH WITH INVERTED V (U+06FF) dbbf Ü€ SYRIAC END OF PARAGRAPH (U+0700) dc80 Ü SYRIAC SUPRALINEAR FULL STOP (U+0701) dc81 Ü‚ SYRIAC SUBLINEAR FULL STOP (U+0702) dc82 ܃ SYRIAC SUPRALINEAR COLON (U+0703) dc83 Ü„ SYRIAC SUBLINEAR COLON (U+0704) dc84 Ü… SYRIAC HORIZONTAL COLON (U+0705) dc85 ܆ SYRIAC COLON SKEWED LEFT (U+0706) dc86 ܇ SYRIAC COLON SKEWED RIGHT (U+0707) dc87 ܈ SYRIAC SUPRALINEAR COLON SKEWED LEFT (U+0708) dc88 ܉ SYRIAC SUBLINEAR COLON SKEWED RIGHT (U+0709) dc89 ÜŠ SYRIAC CONTRACTION (U+070A) dc8a Ü‹ SYRIAC HARKLEAN OBELUS (U+070B) dc8b ÜŒ SYRIAC HARKLEAN METOBELUS (U+070C) dc8c Ü SYRIAC HARKLEAN ASTERISCUS (U+070D) dc8d Ü SYRIAC ABBREVIATION MARK (U+070F) dc8f Ü SYRIAC LETTER ALAPH (U+0710) dc90 Ü‘ SYRIAC LETTER SUPERSCRIPT ALAPH (U+0711) dc91 Ü’ SYRIAC LETTER BETH (U+0712) dc92 Ü“ SYRIAC LETTER GAMAL (U+0713) dc93 Ü” SYRIAC LETTER GAMAL GARSHUNI (U+0714) dc94 Ü• SYRIAC LETTER DALATH (U+0715) dc95 Ü– SYRIAC LETTER DOTLESS DALATH RISH (U+0716) dc96 Ü— SYRIAC LETTER HE (U+0717) dc97 ܘ SYRIAC LETTER WAW (U+0718) dc98 Ü™ SYRIAC LETTER ZAIN (U+0719) dc99 Üš SYRIAC LETTER HETH (U+071A) dc9a Ü› SYRIAC LETTER TETH (U+071B) dc9b Üœ SYRIAC LETTER TETH GARSHUNI (U+071C) dc9c Ü SYRIAC LETTER YUDH (U+071D) dc9d Üž SYRIAC LETTER YUDH HE (U+071E) dc9e ÜŸ SYRIAC LETTER KAPH (U+071F) dc9f Ü  SYRIAC LETTER LAMADH (U+0720) dca0 Ü¡ SYRIAC LETTER MIM (U+0721) dca1 Ü¢ SYRIAC LETTER NUN (U+0722) dca2 Ü£ SYRIAC LETTER SEMKATH (U+0723) dca3 ܤ SYRIAC LETTER FINAL SEMKATH (U+0724) dca4 Ü¥ SYRIAC LETTER E (U+0725) dca5 ܦ SYRIAC LETTER PE (U+0726) dca6 ܧ SYRIAC LETTER REVERSED PE (U+0727) dca7 ܨ SYRIAC LETTER SADHE (U+0728) dca8 Ü© SYRIAC LETTER QAPH (U+0729) dca9 ܪ SYRIAC LETTER RISH (U+072A) dcaa Ü« SYRIAC LETTER SHIN (U+072B) dcab ܬ SYRIAC LETTER TAW (U+072C) dcac Ü­ SYRIAC LETTER PERSIAN BHETH (U+072D) dcad Ü® SYRIAC LETTER PERSIAN GHAMAL (U+072E) dcae ܯ SYRIAC LETTER PERSIAN DHALATH (U+072F) dcaf ܰ SYRIAC PTHAHA ABOVE (U+0730) dcb0 ܱ SYRIAC PTHAHA BELOW (U+0731) dcb1 ܲ SYRIAC PTHAHA DOTTED (U+0732) dcb2 ܳ SYRIAC ZQAPHA ABOVE (U+0733) dcb3 Ü´ SYRIAC ZQAPHA BELOW (U+0734) dcb4 ܵ SYRIAC ZQAPHA DOTTED (U+0735) dcb5 ܶ SYRIAC RBASA ABOVE (U+0736) dcb6 Ü· SYRIAC RBASA BELOW (U+0737) dcb7 ܸ SYRIAC DOTTED ZLAMA HORIZONTAL (U+0738) dcb8 ܹ SYRIAC DOTTED ZLAMA ANGULAR (U+0739) dcb9 ܺ SYRIAC HBASA ABOVE (U+073A) dcba Ü» SYRIAC HBASA BELOW (U+073B) dcbb ܼ SYRIAC HBASA-ESASA DOTTED (U+073C) dcbc ܽ SYRIAC ESASA ABOVE (U+073D) dcbd ܾ SYRIAC ESASA BELOW (U+073E) dcbe Ü¿ SYRIAC RWAHA (U+073F) dcbf Ý€ SYRIAC FEMININE DOT (U+0740) dd80 Ý SYRIAC QUSHSHAYA (U+0741) dd81 Ý‚ SYRIAC RUKKAKHA (U+0742) dd82 ݃ SYRIAC TWO VERTICAL DOTS ABOVE (U+0743) dd83 Ý„ SYRIAC TWO VERTICAL DOTS BELOW (U+0744) dd84 Ý… SYRIAC THREE DOTS ABOVE (U+0745) dd85 ݆ SYRIAC THREE DOTS BELOW (U+0746) dd86 ݇ SYRIAC OBLIQUE LINE ABOVE (U+0747) dd87 ݈ SYRIAC OBLIQUE LINE BELOW (U+0748) dd88 ݉ SYRIAC MUSIC (U+0749) dd89 ÝŠ SYRIAC BARREKH (U+074A) dd8a Ý SYRIAC LETTER SOGDIAN ZHAIN (U+074D) dd8d ÝŽ SYRIAC LETTER SOGDIAN KHAPH (U+074E) dd8e Ý SYRIAC LETTER SOGDIAN FE (U+074F) dd8f Ý ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW (U+0750) dd90 Ý‘ ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE (U+0751) dd91 Ý’ ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW (U+0752) dd92 Ý“ ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE (U+0753) dd93 Ý” ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE (U+0754) dd94 Ý• ARABIC LETTER BEH WITH INVERTED SMALL V BELOW (U+0755) dd95 Ý– ARABIC LETTER BEH WITH SMALL V (U+0756) dd96 Ý— ARABIC LETTER HAH WITH TWO DOTS ABOVE (U+0757) dd97 ݘ ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW (U+0758) dd98 Ý™ ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH (U+0759) dd99 Ýš ARABIC LETTER DAL WITH INVERTED SMALL V BELOW (U+075A) dd9a Ý› ARABIC LETTER REH WITH STROKE (U+075B) dd9b Ýœ ARABIC LETTER SEEN WITH FOUR DOTS ABOVE (U+075C) dd9c Ý ARABIC LETTER AIN WITH TWO DOTS ABOVE (U+075D) dd9d Ýž ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE (U+075E) dd9e ÝŸ ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE (U+075F) dd9f Ý  ARABIC LETTER FEH WITH TWO DOTS BELOW (U+0760) dda0 Ý¡ ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW (U+0761) dda1 Ý¢ ARABIC LETTER KEHEH WITH DOT ABOVE (U+0762) dda2 Ý£ ARABIC LETTER KEHEH WITH THREE DOTS ABOVE (U+0763) dda3 ݤ ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW (U+0764) dda4 Ý¥ ARABIC LETTER MEEM WITH DOT ABOVE (U+0765) dda5 ݦ ARABIC LETTER MEEM WITH DOT BELOW (U+0766) dda6 ݧ ARABIC LETTER NOON WITH TWO DOTS BELOW (U+0767) dda7 ݨ ARABIC LETTER NOON WITH SMALL TAH (U+0768) dda8 Ý© ARABIC LETTER NOON WITH SMALL V (U+0769) dda9 ݪ ARABIC LETTER LAM WITH BAR (U+076A) ddaa Ý« ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE (U+076B) ddab ݬ ARABIC LETTER REH WITH HAMZA ABOVE (U+076C) ddac Ý­ ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE (U+076D) ddad Ý® ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW (U+076E) ddae ݯ ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS (U+076F) ddaf ݰ ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS (U+0770) ddb0 ݱ ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS (U+0771) ddb1 ݲ ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE (U+0772) ddb2 ݳ ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE (U+0773) ddb3 Ý´ ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE (U+0774) ddb4 ݵ ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE (U+0775) ddb5 ݶ ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE (U+0776) ddb6 Ý· ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW (U+0777) ddb7 ݸ ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE (U+0778) ddb8 ݹ ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE (U+0779) ddb9 ݺ ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE (U+077A) ddba Ý» ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE (U+077B) ddbb ݼ ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW (U+077C) ddbc ݽ ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE (U+077D) ddbd ݾ ARABIC LETTER SEEN WITH INVERTED V (U+077E) ddbe Ý¿ ARABIC LETTER KAF WITH TWO DOTS ABOVE (U+077F) ddbf Þ€ THAANA LETTER HAA (U+0780) de80 Þ THAANA LETTER SHAVIYANI (U+0781) de81 Þ‚ THAANA LETTER NOONU (U+0782) de82 Þƒ THAANA LETTER RAA (U+0783) de83 Þ„ THAANA LETTER BAA (U+0784) de84 Þ… THAANA LETTER LHAVIYANI (U+0785) de85 Þ† THAANA LETTER KAAFU (U+0786) de86 Þ‡ THAANA LETTER ALIFU (U+0787) de87 Þˆ THAANA LETTER VAAVU (U+0788) de88 Þ‰ THAANA LETTER MEEMU (U+0789) de89 ÞŠ THAANA LETTER FAAFU (U+078A) de8a Þ‹ THAANA LETTER DHAALU (U+078B) de8b ÞŒ THAANA LETTER THAA (U+078C) de8c Þ THAANA LETTER LAAMU (U+078D) de8d ÞŽ THAANA LETTER GAAFU (U+078E) de8e Þ THAANA LETTER GNAVIYANI (U+078F) de8f Þ THAANA LETTER SEENU (U+0790) de90 Þ‘ THAANA LETTER DAVIYANI (U+0791) de91 Þ’ THAANA LETTER ZAVIYANI (U+0792) de92 Þ“ THAANA LETTER TAVIYANI (U+0793) de93 Þ” THAANA LETTER YAA (U+0794) de94 Þ• THAANA LETTER PAVIYANI (U+0795) de95 Þ– THAANA LETTER JAVIYANI (U+0796) de96 Þ— THAANA LETTER CHAVIYANI (U+0797) de97 Þ˜ THAANA LETTER TTAA (U+0798) de98 Þ™ THAANA LETTER HHAA (U+0799) de99 Þš THAANA LETTER KHAA (U+079A) de9a Þ› THAANA LETTER THAALU (U+079B) de9b Þœ THAANA LETTER ZAA (U+079C) de9c Þ THAANA LETTER SHEENU (U+079D) de9d Þž THAANA LETTER SAADHU (U+079E) de9e ÞŸ THAANA LETTER DAADHU (U+079F) de9f Þ  THAANA LETTER TO (U+07A0) dea0 Þ¡ THAANA LETTER ZO (U+07A1) dea1 Þ¢ THAANA LETTER AINU (U+07A2) dea2 Þ£ THAANA LETTER GHAINU (U+07A3) dea3 Þ¤ THAANA LETTER QAAFU (U+07A4) dea4 Þ¥ THAANA LETTER WAAVU (U+07A5) dea5 Þ¦ THAANA ABAFILI (U+07A6) dea6 Þ§ THAANA AABAAFILI (U+07A7) dea7 Þ¨ THAANA IBIFILI (U+07A8) dea8 Þ© THAANA EEBEEFILI (U+07A9) dea9 Þª THAANA UBUFILI (U+07AA) deaa Þ« THAANA OOBOOFILI (U+07AB) deab Þ¬ THAANA EBEFILI (U+07AC) deac Þ­ THAANA EYBEYFILI (U+07AD) dead Þ® THAANA OBOFILI (U+07AE) deae Þ¯ THAANA OABOAFILI (U+07AF) deaf Þ° THAANA SUKUN (U+07B0) deb0 Þ± THAANA LETTER NAA (U+07B1) deb1 ߀ NKO DIGIT ZERO (U+07C0) df80 ß NKO DIGIT ONE (U+07C1) df81 ß‚ NKO DIGIT TWO (U+07C2) df82 ߃ NKO DIGIT THREE (U+07C3) df83 ß„ NKO DIGIT FOUR (U+07C4) df84 ß… NKO DIGIT FIVE (U+07C5) df85 ߆ NKO DIGIT SIX (U+07C6) df86 ߇ NKO DIGIT SEVEN (U+07C7) df87 ߈ NKO DIGIT EIGHT (U+07C8) df88 ߉ NKO DIGIT NINE (U+07C9) df89 ߊ NKO LETTER A (U+07CA) df8a ß‹ NKO LETTER EE (U+07CB) df8b ߌ NKO LETTER I (U+07CC) df8c ß NKO LETTER E (U+07CD) df8d ߎ NKO LETTER U (U+07CE) df8e ß NKO LETTER OO (U+07CF) df8f ß NKO LETTER O (U+07D0) df90 ß‘ NKO LETTER DAGBASINNA (U+07D1) df91 ß’ NKO LETTER N (U+07D2) df92 ß“ NKO LETTER BA (U+07D3) df93 ß” NKO LETTER PA (U+07D4) df94 ß• NKO LETTER TA (U+07D5) df95 ß– NKO LETTER JA (U+07D6) df96 ß— NKO LETTER CHA (U+07D7) df97 ߘ NKO LETTER DA (U+07D8) df98 ß™ NKO LETTER RA (U+07D9) df99 ßš NKO LETTER RRA (U+07DA) df9a ß› NKO LETTER SA (U+07DB) df9b ßœ NKO LETTER GBA (U+07DC) df9c ß NKO LETTER FA (U+07DD) df9d ßž NKO LETTER KA (U+07DE) df9e ߟ NKO LETTER LA (U+07DF) df9f ß  NKO LETTER NA WOLOSO (U+07E0) dfa0 ß¡ NKO LETTER MA (U+07E1) dfa1 ߢ NKO LETTER NYA (U+07E2) dfa2 ߣ NKO LETTER NA (U+07E3) dfa3 ߤ NKO LETTER HA (U+07E4) dfa4 ߥ NKO LETTER WA (U+07E5) dfa5 ߦ NKO LETTER YA (U+07E6) dfa6 ß§ NKO LETTER NYA WOLOSO (U+07E7) dfa7 ߨ NKO LETTER JONA JA (U+07E8) dfa8 ß© NKO LETTER JONA CHA (U+07E9) dfa9 ߪ NKO LETTER JONA RA (U+07EA) dfaa ß« NKO COMBINING SHORT HIGH TONE (U+07EB) dfab ߬ NKO COMBINING SHORT LOW TONE (U+07EC) dfac ß­ NKO COMBINING SHORT RISING TONE (U+07ED) dfad ß® NKO COMBINING LONG DESCENDING TONE (U+07EE) dfae ߯ NKO COMBINING LONG HIGH TONE (U+07EF) dfaf ß° NKO COMBINING LONG LOW TONE (U+07F0) dfb0 ß± NKO COMBINING LONG RISING TONE (U+07F1) dfb1 ß² NKO COMBINING NASALIZATION MARK (U+07F2) dfb2 ß³ NKO COMBINING DOUBLE DOT ABOVE (U+07F3) dfb3 ß´ NKO HIGH TONE APOSTROPHE (U+07F4) dfb4 ßµ NKO LOW TONE APOSTROPHE (U+07F5) dfb5 ß¶ NKO SYMBOL OO DENNEN (U+07F6) dfb6 ß· NKO SYMBOL GBAKURUNEN (U+07F7) dfb7 ߸ NKO COMMA (U+07F8) dfb8 ß¹ NKO EXCLAMATION MARK (U+07F9) dfb9 ߺ NKO LAJANYALAN (U+07FA) dfba à € SAMARITAN LETTER ALAF (U+0800) e0a080 à  SAMARITAN LETTER BIT (U+0801) e0a081 à ‚ SAMARITAN LETTER GAMAN (U+0802) e0a082 à ƒ SAMARITAN LETTER DALAT (U+0803) e0a083 à „ SAMARITAN LETTER IY (U+0804) e0a084 à … SAMARITAN LETTER BAA (U+0805) e0a085 à † SAMARITAN LETTER ZEN (U+0806) e0a086 à ‡ SAMARITAN LETTER IT (U+0807) e0a087 à ˆ SAMARITAN LETTER TIT (U+0808) e0a088 à ‰ SAMARITAN LETTER YUT (U+0809) e0a089 à Š SAMARITAN LETTER KAAF (U+080A) e0a08a à ‹ SAMARITAN LETTER LABAT (U+080B) e0a08b à Œ SAMARITAN LETTER MIM (U+080C) e0a08c à  SAMARITAN LETTER NUN (U+080D) e0a08d à Ž SAMARITAN LETTER SINGAAT (U+080E) e0a08e à  SAMARITAN LETTER IN (U+080F) e0a08f à  SAMARITAN LETTER FI (U+0810) e0a090 à ‘ SAMARITAN LETTER TSAADIY (U+0811) e0a091 à ’ SAMARITAN LETTER QUF (U+0812) e0a092 à “ SAMARITAN LETTER RISH (U+0813) e0a093 à ” SAMARITAN LETTER SHAN (U+0814) e0a094 à • SAMARITAN LETTER TAAF (U+0815) e0a095 à – SAMARITAN MARK IN (U+0816) e0a096 à — SAMARITAN MARK IN-ALAF (U+0817) e0a097 à ˜ SAMARITAN MARK OCCLUSION (U+0818) e0a098 à ™ SAMARITAN MARK DAGESH (U+0819) e0a099 à š SAMARITAN MODIFIER LETTER EPENTHETIC YUT (U+081A) e0a09a à › SAMARITAN MARK EPENTHETIC YUT (U+081B) e0a09b à œ SAMARITAN VOWEL SIGN LONG E (U+081C) e0a09c à  SAMARITAN VOWEL SIGN E (U+081D) e0a09d à ž SAMARITAN VOWEL SIGN OVERLONG AA (U+081E) e0a09e à Ÿ SAMARITAN VOWEL SIGN LONG AA (U+081F) e0a09f à   SAMARITAN VOWEL SIGN AA (U+0820) e0a0a0 à ¡ SAMARITAN VOWEL SIGN OVERLONG A (U+0821) e0a0a1 à ¢ SAMARITAN VOWEL SIGN LONG A (U+0822) e0a0a2 à £ SAMARITAN VOWEL SIGN A (U+0823) e0a0a3 à ¤ SAMARITAN MODIFIER LETTER SHORT A (U+0824) e0a0a4 à ¥ SAMARITAN VOWEL SIGN SHORT A (U+0825) e0a0a5 à ¦ SAMARITAN VOWEL SIGN LONG U (U+0826) e0a0a6 à § SAMARITAN VOWEL SIGN U (U+0827) e0a0a7 à ¨ SAMARITAN MODIFIER LETTER I (U+0828) e0a0a8 à © SAMARITAN VOWEL SIGN LONG I (U+0829) e0a0a9 à ª SAMARITAN VOWEL SIGN I (U+082A) e0a0aa à « SAMARITAN VOWEL SIGN O (U+082B) e0a0ab à ¬ SAMARITAN VOWEL SIGN SUKUN (U+082C) e0a0ac à ­ SAMARITAN MARK NEQUDAA (U+082D) e0a0ad à ° SAMARITAN PUNCTUATION NEQUDAA (U+0830) e0a0b0 à ± SAMARITAN PUNCTUATION AFSAAQ (U+0831) e0a0b1 à ² SAMARITAN PUNCTUATION ANGED (U+0832) e0a0b2 à ³ SAMARITAN PUNCTUATION BAU (U+0833) e0a0b3 à ´ SAMARITAN PUNCTUATION ATMAAU (U+0834) e0a0b4 à µ SAMARITAN PUNCTUATION SHIYYAALAA (U+0835) e0a0b5 à ¶ SAMARITAN ABBREVIATION MARK (U+0836) e0a0b6 à · SAMARITAN PUNCTUATION MELODIC QITSA (U+0837) e0a0b7 à ¸ SAMARITAN PUNCTUATION ZIQAA (U+0838) e0a0b8 à ¹ SAMARITAN PUNCTUATION QITSA (U+0839) e0a0b9 à º SAMARITAN PUNCTUATION ZAEF (U+083A) e0a0ba à » SAMARITAN PUNCTUATION TURU (U+083B) e0a0bb à ¼ SAMARITAN PUNCTUATION ARKAANU (U+083C) e0a0bc à ½ SAMARITAN PUNCTUATION SOF MASHFAAT (U+083D) e0a0bd à ¾ SAMARITAN PUNCTUATION ANNAAU (U+083E) e0a0be à¡€ MANDAIC LETTER HALQA (U+0840) e0a180 à¡ MANDAIC LETTER AB (U+0841) e0a181 à¡‚ MANDAIC LETTER AG (U+0842) e0a182 ࡃ MANDAIC LETTER AD (U+0843) e0a183 à¡„ MANDAIC LETTER AH (U+0844) e0a184 à¡… MANDAIC LETTER USHENNA (U+0845) e0a185 ࡆ MANDAIC LETTER AZ (U+0846) e0a186 ࡇ MANDAIC LETTER IT (U+0847) e0a187 ࡈ MANDAIC LETTER ATT (U+0848) e0a188 ࡉ MANDAIC LETTER AKSA (U+0849) e0a189 ࡊ MANDAIC LETTER AK (U+084A) e0a18a à¡‹ MANDAIC LETTER AL (U+084B) e0a18b ࡌ MANDAIC LETTER AM (U+084C) e0a18c à¡ MANDAIC LETTER AN (U+084D) e0a18d ࡎ MANDAIC LETTER AS (U+084E) e0a18e à¡ MANDAIC LETTER IN (U+084F) e0a18f à¡ MANDAIC LETTER AP (U+0850) e0a190 à¡‘ MANDAIC LETTER ASZ (U+0851) e0a191 More... à¡’ MANDAIC LETTER AQ (U+0852) e0a192 à¡“ MANDAIC LETTER AR (U+0853) e0a193 à¡” MANDAIC LETTER ASH (U+0854) e0a194 à¡• MANDAIC LETTER AT (U+0855) e0a195 à¡– MANDAIC LETTER DUSHENNA (U+0856) e0a196 à¡— MANDAIC LETTER KAD (U+0857) e0a197 ࡘ MANDAIC LETTER AIN (U+0858) e0a198 à¡™ MANDAIC AFFRICATION MARK (U+0859) e0a199 ࡚ MANDAIC VOCALIZATION MARK (U+085A) e0a19a à¡› MANDAIC GEMINATION MARK (U+085B) e0a19b ࡞ MANDAIC PUNCTUATION (U+085E) e0a19e ऀ DEVANAGARI SIGN INVERTED CANDRABINDU (U+0900) e0a480 ठDEVANAGARI SIGN CANDRABINDU (U+0901) e0a481 ं DEVANAGARI SIGN ANUSVARA (U+0902) e0a482 ः DEVANAGARI SIGN VISARGA (U+0903) e0a483 ऄ DEVANAGARI LETTER SHORT A (U+0904) e0a484 अ DEVANAGARI LETTER A (U+0905) e0a485 आ DEVANAGARI LETTER AA (U+0906) e0a486 इ DEVANAGARI LETTER I (U+0907) e0a487 ई DEVANAGARI LETTER II (U+0908) e0a488 उ DEVANAGARI LETTER U (U+0909) e0a489 ऊ DEVANAGARI LETTER UU (U+090A) e0a48a ऋ DEVANAGARI LETTER VOCALIC R (U+090B) e0a48b ऌ DEVANAGARI LETTER VOCALIC L (U+090C) e0a48c ठDEVANAGARI LETTER CANDRA E (U+090D) e0a48d ऎ DEVANAGARI LETTER SHORT E (U+090E) e0a48e ठDEVANAGARI LETTER E (U+090F) e0a48f ठDEVANAGARI LETTER AI (U+0910) e0a490 ऑ DEVANAGARI LETTER CANDRA O (U+0911) e0a491 ऒ DEVANAGARI LETTER SHORT O (U+0912) e0a492 ओ DEVANAGARI LETTER O (U+0913) e0a493 औ DEVANAGARI LETTER AU (U+0914) e0a494 क DEVANAGARI LETTER KA (U+0915) e0a495 ख DEVANAGARI LETTER KHA (U+0916) e0a496 ग DEVANAGARI LETTER GA (U+0917) e0a497 घ DEVANAGARI LETTER GHA (U+0918) e0a498 ङ DEVANAGARI LETTER NGA (U+0919) e0a499 च DEVANAGARI LETTER CA (U+091A) e0a49a छ DEVANAGARI LETTER CHA (U+091B) e0a49b ज DEVANAGARI LETTER JA (U+091C) e0a49c ठDEVANAGARI LETTER JHA (U+091D) e0a49d ञ DEVANAGARI LETTER NYA (U+091E) e0a49e ट DEVANAGARI LETTER TTA (U+091F) e0a49f ठ DEVANAGARI LETTER TTHA (U+0920) e0a4a0 ड DEVANAGARI LETTER DDA (U+0921) e0a4a1 ढ DEVANAGARI LETTER DDHA (U+0922) e0a4a2 ण DEVANAGARI LETTER NNA (U+0923) e0a4a3 त DEVANAGARI LETTER TA (U+0924) e0a4a4 थ DEVANAGARI LETTER THA (U+0925) e0a4a5 द DEVANAGARI LETTER DA (U+0926) e0a4a6 ध DEVANAGARI LETTER DHA (U+0927) e0a4a7 न DEVANAGARI LETTER NA (U+0928) e0a4a8 ऩ DEVANAGARI LETTER NNNA (U+0929) e0a4a9 प DEVANAGARI LETTER PA (U+092A) e0a4aa फ DEVANAGARI LETTER PHA (U+092B) e0a4ab ब DEVANAGARI LETTER BA (U+092C) e0a4ac भ DEVANAGARI LETTER BHA (U+092D) e0a4ad म DEVANAGARI LETTER MA (U+092E) e0a4ae य DEVANAGARI LETTER YA (U+092F) e0a4af र DEVANAGARI LETTER RA (U+0930) e0a4b0 ऱ DEVANAGARI LETTER RRA (U+0931) e0a4b1 ल DEVANAGARI LETTER LA (U+0932) e0a4b2 ळ DEVANAGARI LETTER LLA (U+0933) e0a4b3 ऴ DEVANAGARI LETTER LLLA (U+0934) e0a4b4 व DEVANAGARI LETTER VA (U+0935) e0a4b5 श DEVANAGARI LETTER SHA (U+0936) e0a4b6 ष DEVANAGARI LETTER SSA (U+0937) e0a4b7 स DEVANAGARI LETTER SA (U+0938) e0a4b8 ह DEVANAGARI LETTER HA (U+0939) e0a4b9 ऺ DEVANAGARI VOWEL SIGN OE (U+093A) e0a4ba ऻ DEVANAGARI VOWEL SIGN OOE (U+093B) e0a4bb ़ DEVANAGARI SIGN NUKTA (U+093C) e0a4bc ऽ DEVANAGARI SIGN AVAGRAHA (U+093D) e0a4bd ा DEVANAGARI VOWEL SIGN AA (U+093E) e0a4be ि DEVANAGARI VOWEL SIGN I (U+093F) e0a4bf ी DEVANAGARI VOWEL SIGN II (U+0940) e0a580 ॠDEVANAGARI VOWEL SIGN U (U+0941) e0a581 ू DEVANAGARI VOWEL SIGN UU (U+0942) e0a582 ृ DEVANAGARI VOWEL SIGN VOCALIC R (U+0943) e0a583 ॄ DEVANAGARI VOWEL SIGN VOCALIC RR (U+0944) e0a584 ॅ DEVANAGARI VOWEL SIGN CANDRA E (U+0945) e0a585 ॆ DEVANAGARI VOWEL SIGN SHORT E (U+0946) e0a586 े DEVANAGARI VOWEL SIGN E (U+0947) e0a587 ै DEVANAGARI VOWEL SIGN AI (U+0948) e0a588 ॉ DEVANAGARI VOWEL SIGN CANDRA O (U+0949) e0a589 ॊ DEVANAGARI VOWEL SIGN SHORT O (U+094A) e0a58a ो DEVANAGARI VOWEL SIGN O (U+094B) e0a58b ौ DEVANAGARI VOWEL SIGN AU (U+094C) e0a58c ॠDEVANAGARI SIGN VIRAMA (U+094D) e0a58d ॎ DEVANAGARI VOWEL SIGN PRISHTHAMATRA E (U+094E) e0a58e ॠDEVANAGARI VOWEL SIGN AW (U+094F) e0a58f ॠDEVANAGARI OM (U+0950) e0a590 ॑ DEVANAGARI STRESS SIGN UDATTA (U+0951) e0a591 ॒ DEVANAGARI STRESS SIGN ANUDATTA (U+0952) e0a592 ॓ DEVANAGARI GRAVE ACCENT (U+0953) e0a593 ॔ DEVANAGARI ACUTE ACCENT (U+0954) e0a594 ॕ DEVANAGARI VOWEL SIGN CANDRA LONG E (U+0955) e0a595 ॖ DEVANAGARI VOWEL SIGN UE (U+0956) e0a596 ॗ DEVANAGARI VOWEL SIGN UUE (U+0957) e0a597 क़ DEVANAGARI LETTER QA (U+0958) e0a598 ख़ DEVANAGARI LETTER KHHA (U+0959) e0a599 ग़ DEVANAGARI LETTER GHHA (U+095A) e0a59a ज़ DEVANAGARI LETTER ZA (U+095B) e0a59b ड़ DEVANAGARI LETTER DDDHA (U+095C) e0a59c ॠDEVANAGARI LETTER RHA (U+095D) e0a59d फ़ DEVANAGARI LETTER FA (U+095E) e0a59e य़ DEVANAGARI LETTER YYA (U+095F) e0a59f ॠ DEVANAGARI LETTER VOCALIC RR (U+0960) e0a5a0 ॡ DEVANAGARI LETTER VOCALIC LL (U+0961) e0a5a1 ॢ DEVANAGARI VOWEL SIGN VOCALIC L (U+0962) e0a5a2 ॣ DEVANAGARI VOWEL SIGN VOCALIC LL (U+0963) e0a5a3 । DEVANAGARI DANDA (U+0964) e0a5a4 ॥ DEVANAGARI DOUBLE DANDA (U+0965) e0a5a5 ० DEVANAGARI DIGIT ZERO (U+0966) e0a5a6 १ DEVANAGARI DIGIT ONE (U+0967) e0a5a7 २ DEVANAGARI DIGIT TWO (U+0968) e0a5a8 ३ DEVANAGARI DIGIT THREE (U+0969) e0a5a9 ४ DEVANAGARI DIGIT FOUR (U+096A) e0a5aa ५ DEVANAGARI DIGIT FIVE (U+096B) e0a5ab ६ DEVANAGARI DIGIT SIX (U+096C) e0a5ac ७ DEVANAGARI DIGIT SEVEN (U+096D) e0a5ad ८ DEVANAGARI DIGIT EIGHT (U+096E) e0a5ae ९ DEVANAGARI DIGIT NINE (U+096F) e0a5af ॰ DEVANAGARI ABBREVIATION SIGN (U+0970) e0a5b0 ॱ DEVANAGARI SIGN HIGH SPACING DOT (U+0971) e0a5b1 ॲ DEVANAGARI LETTER CANDRA A (U+0972) e0a5b2 ॳ DEVANAGARI LETTER OE (U+0973) e0a5b3 ॴ DEVANAGARI LETTER OOE (U+0974) e0a5b4 ॵ DEVANAGARI LETTER AW (U+0975) e0a5b5 ॶ DEVANAGARI LETTER UE (U+0976) e0a5b6 ॷ DEVANAGARI LETTER UUE (U+0977) e0a5b7 ॹ DEVANAGARI LETTER ZHA (U+0979) e0a5b9 ॺ DEVANAGARI LETTER HEAVY YA (U+097A) e0a5ba ॻ DEVANAGARI LETTER GGA (U+097B) e0a5bb ॼ DEVANAGARI LETTER JJA (U+097C) e0a5bc ॽ DEVANAGARI LETTER GLOTTAL STOP (U+097D) e0a5bd ॾ DEVANAGARI LETTER DDDA (U+097E) e0a5be ॿ DEVANAGARI LETTER BBA (U+097F) e0a5bf ঠBENGALI SIGN CANDRABINDU (U+0981) e0a681 ং BENGALI SIGN ANUSVARA (U+0982) e0a682 ঃ BENGALI SIGN VISARGA (U+0983) e0a683 অ BENGALI LETTER A (U+0985) e0a685 আ BENGALI LETTER AA (U+0986) e0a686 ই BENGALI LETTER I (U+0987) e0a687 ঈ BENGALI LETTER II (U+0988) e0a688 উ BENGALI LETTER U (U+0989) e0a689 ঊ BENGALI LETTER UU (U+098A) e0a68a ঋ BENGALI LETTER VOCALIC R (U+098B) e0a68b ঌ BENGALI LETTER VOCALIC L (U+098C) e0a68c ঠBENGALI LETTER E (U+098F) e0a68f ঠBENGALI LETTER AI (U+0990) e0a690 ও BENGALI LETTER O (U+0993) e0a693 ঔ BENGALI LETTER AU (U+0994) e0a694 ক BENGALI LETTER KA (U+0995) e0a695 খ BENGALI LETTER KHA (U+0996) e0a696 গ BENGALI LETTER GA (U+0997) e0a697 ঘ BENGALI LETTER GHA (U+0998) e0a698 ঙ BENGALI LETTER NGA (U+0999) e0a699 চ BENGALI LETTER CA (U+099A) e0a69a ছ BENGALI LETTER CHA (U+099B) e0a69b জ BENGALI LETTER JA (U+099C) e0a69c ঠBENGALI LETTER JHA (U+099D) e0a69d ঞ BENGALI LETTER NYA (U+099E) e0a69e ট BENGALI LETTER TTA (U+099F) e0a69f ঠ BENGALI LETTER TTHA (U+09A0) e0a6a0 ড BENGALI LETTER DDA (U+09A1) e0a6a1 ঢ BENGALI LETTER DDHA (U+09A2) e0a6a2 ণ BENGALI LETTER NNA (U+09A3) e0a6a3 ত BENGALI LETTER TA (U+09A4) e0a6a4 থ BENGALI LETTER THA (U+09A5) e0a6a5 দ BENGALI LETTER DA (U+09A6) e0a6a6 ধ BENGALI LETTER DHA (U+09A7) e0a6a7 ন BENGALI LETTER NA (U+09A8) e0a6a8 প BENGALI LETTER PA (U+09AA) e0a6aa ফ BENGALI LETTER PHA (U+09AB) e0a6ab ব BENGALI LETTER BA (U+09AC) e0a6ac ভ BENGALI LETTER BHA (U+09AD) e0a6ad ম BENGALI LETTER MA (U+09AE) e0a6ae য BENGALI LETTER YA (U+09AF) e0a6af র BENGALI LETTER RA (U+09B0) e0a6b0 ল BENGALI LETTER LA (U+09B2) e0a6b2 শ BENGALI LETTER SHA (U+09B6) e0a6b6 ষ BENGALI LETTER SSA (U+09B7) e0a6b7 স BENGALI LETTER SA (U+09B8) e0a6b8 হ BENGALI LETTER HA (U+09B9) e0a6b9 ় BENGALI SIGN NUKTA (U+09BC) e0a6bc ঽ BENGALI SIGN AVAGRAHA (U+09BD) e0a6bd া BENGALI VOWEL SIGN AA (U+09BE) e0a6be ি BENGALI VOWEL SIGN I (U+09BF) e0a6bf à§€ BENGALI VOWEL SIGN II (U+09C0) e0a780 à§ BENGALI VOWEL SIGN U (U+09C1) e0a781 à§‚ BENGALI VOWEL SIGN UU (U+09C2) e0a782 ৃ BENGALI VOWEL SIGN VOCALIC R (U+09C3) e0a783 à§„ BENGALI VOWEL SIGN VOCALIC RR (U+09C4) e0a784 ে BENGALI VOWEL SIGN E (U+09C7) e0a787 ৈ BENGALI VOWEL SIGN AI (U+09C8) e0a788 à§‹ BENGALI VOWEL SIGN O (U+09CB) e0a78b à§Œ BENGALI VOWEL SIGN AU (U+09CC) e0a78c à§ BENGALI SIGN VIRAMA (U+09CD) e0a78d à§Ž BENGALI LETTER KHANDA TA (U+09CE) e0a78e à§— BENGALI AU LENGTH MARK (U+09D7) e0a797 à§œ BENGALI LETTER RRA (U+09DC) e0a79c à§ BENGALI LETTER RHA (U+09DD) e0a79d à§Ÿ BENGALI LETTER YYA (U+09DF) e0a79f à§  BENGALI LETTER VOCALIC RR (U+09E0) e0a7a0 à§¡ BENGALI LETTER VOCALIC LL (U+09E1) e0a7a1 à§¢ BENGALI VOWEL SIGN VOCALIC L (U+09E2) e0a7a2 à§£ BENGALI VOWEL SIGN VOCALIC LL (U+09E3) e0a7a3 ০ BENGALI DIGIT ZERO (U+09E6) e0a7a6 à§§ BENGALI DIGIT ONE (U+09E7) e0a7a7 ২ BENGALI DIGIT TWO (U+09E8) e0a7a8 à§© BENGALI DIGIT THREE (U+09E9) e0a7a9 ৪ BENGALI DIGIT FOUR (U+09EA) e0a7aa à§« BENGALI DIGIT FIVE (U+09EB) e0a7ab ৬ BENGALI DIGIT SIX (U+09EC) e0a7ac à§­ BENGALI DIGIT SEVEN (U+09ED) e0a7ad à§® BENGALI DIGIT EIGHT (U+09EE) e0a7ae ৯ BENGALI DIGIT NINE (U+09EF) e0a7af à§° BENGALI LETTER RA WITH MIDDLE DIAGONAL (U+09F0) e0a7b0 à§± BENGALI LETTER RA WITH LOWER DIAGONAL (U+09F1) e0a7b1 à§² BENGALI RUPEE MARK (U+09F2) e0a7b2 à§³ BENGALI RUPEE SIGN (U+09F3) e0a7b3 à§´ BENGALI CURRENCY NUMERATOR ONE (U+09F4) e0a7b4 à§µ BENGALI CURRENCY NUMERATOR TWO (U+09F5) e0a7b5 à§¶ BENGALI CURRENCY NUMERATOR THREE (U+09F6) e0a7b6 à§· BENGALI CURRENCY NUMERATOR FOUR (U+09F7) e0a7b7 ৸ BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR (U+09F8) e0a7b8 à§¹ BENGALI CURRENCY DENOMINATOR SIXTEEN (U+09F9) e0a7b9 ৺ BENGALI ISSHAR (U+09FA) e0a7ba à§» BENGALI GANDA MARK (U+09FB) e0a7bb ਠGURMUKHI SIGN ADAK BINDI (U+0A01) e0a881 ਂ GURMUKHI SIGN BINDI (U+0A02) e0a882 ਃ GURMUKHI SIGN VISARGA (U+0A03) e0a883 ਅ GURMUKHI LETTER A (U+0A05) e0a885 ਆ GURMUKHI LETTER AA (U+0A06) e0a886 ਇ GURMUKHI LETTER I (U+0A07) e0a887 ਈ GURMUKHI LETTER II (U+0A08) e0a888 ਉ GURMUKHI LETTER U (U+0A09) e0a889 ਊ GURMUKHI LETTER UU (U+0A0A) e0a88a ਠGURMUKHI LETTER EE (U+0A0F) e0a88f ਠGURMUKHI LETTER AI (U+0A10) e0a890 ਓ GURMUKHI LETTER OO (U+0A13) e0a893 ਔ GURMUKHI LETTER AU (U+0A14) e0a894 ਕ GURMUKHI LETTER KA (U+0A15) e0a895 ਖ GURMUKHI LETTER KHA (U+0A16) e0a896 ਗ GURMUKHI LETTER GA (U+0A17) e0a897 ਘ GURMUKHI LETTER GHA (U+0A18) e0a898 ਙ GURMUKHI LETTER NGA (U+0A19) e0a899 ਚ GURMUKHI LETTER CA (U+0A1A) e0a89a ਛ GURMUKHI LETTER CHA (U+0A1B) e0a89b ਜ GURMUKHI LETTER JA (U+0A1C) e0a89c ਠGURMUKHI LETTER JHA (U+0A1D) e0a89d ਞ GURMUKHI LETTER NYA (U+0A1E) e0a89e ਟ GURMUKHI LETTER TTA (U+0A1F) e0a89f ਠ GURMUKHI LETTER TTHA (U+0A20) e0a8a0 ਡ GURMUKHI LETTER DDA (U+0A21) e0a8a1 ਢ GURMUKHI LETTER DDHA (U+0A22) e0a8a2 ਣ GURMUKHI LETTER NNA (U+0A23) e0a8a3 ਤ GURMUKHI LETTER TA (U+0A24) e0a8a4 ਥ GURMUKHI LETTER THA (U+0A25) e0a8a5 ਦ GURMUKHI LETTER DA (U+0A26) e0a8a6 ਧ GURMUKHI LETTER DHA (U+0A27) e0a8a7 ਨ GURMUKHI LETTER NA (U+0A28) e0a8a8 ਪ GURMUKHI LETTER PA (U+0A2A) e0a8aa ਫ GURMUKHI LETTER PHA (U+0A2B) e0a8ab ਬ GURMUKHI LETTER BA (U+0A2C) e0a8ac ਭ GURMUKHI LETTER BHA (U+0A2D) e0a8ad ਮ GURMUKHI LETTER MA (U+0A2E) e0a8ae ਯ GURMUKHI LETTER YA (U+0A2F) e0a8af ਰ GURMUKHI LETTER RA (U+0A30) e0a8b0 ਲ GURMUKHI LETTER LA (U+0A32) e0a8b2 ਲ਼ GURMUKHI LETTER LLA (U+0A33) e0a8b3 ਵ GURMUKHI LETTER VA (U+0A35) e0a8b5 ਸ਼ GURMUKHI LETTER SHA (U+0A36) e0a8b6 ਸ GURMUKHI LETTER SA (U+0A38) e0a8b8 ਹ GURMUKHI LETTER HA (U+0A39) e0a8b9 ਼ GURMUKHI SIGN NUKTA (U+0A3C) e0a8bc ਾ GURMUKHI VOWEL SIGN AA (U+0A3E) e0a8be ਿ GURMUKHI VOWEL SIGN I (U+0A3F) e0a8bf à©€ GURMUKHI VOWEL SIGN II (U+0A40) e0a980 à© GURMUKHI VOWEL SIGN U (U+0A41) e0a981 à©‚ GURMUKHI VOWEL SIGN UU (U+0A42) e0a982 ੇ GURMUKHI VOWEL SIGN EE (U+0A47) e0a987 ੈ GURMUKHI VOWEL SIGN AI (U+0A48) e0a988 à©‹ GURMUKHI VOWEL SIGN OO (U+0A4B) e0a98b ੌ GURMUKHI VOWEL SIGN AU (U+0A4C) e0a98c à© GURMUKHI SIGN VIRAMA (U+0A4D) e0a98d à©‘ GURMUKHI SIGN UDAAT (U+0A51) e0a991 à©™ GURMUKHI LETTER KHHA (U+0A59) e0a999 ਗ਼ GURMUKHI LETTER GHHA (U+0A5A) e0a99a à©› GURMUKHI LETTER ZA (U+0A5B) e0a99b ੜ GURMUKHI LETTER RRA (U+0A5C) e0a99c ਫ਼ GURMUKHI LETTER FA (U+0A5E) e0a99e ੦ GURMUKHI DIGIT ZERO (U+0A66) e0a9a6 à©§ GURMUKHI DIGIT ONE (U+0A67) e0a9a7 ੨ GURMUKHI DIGIT TWO (U+0A68) e0a9a8 à©© GURMUKHI DIGIT THREE (U+0A69) e0a9a9 ੪ GURMUKHI DIGIT FOUR (U+0A6A) e0a9aa à©« GURMUKHI DIGIT FIVE (U+0A6B) e0a9ab ੬ GURMUKHI DIGIT SIX (U+0A6C) e0a9ac à©­ GURMUKHI DIGIT SEVEN (U+0A6D) e0a9ad à©® GURMUKHI DIGIT EIGHT (U+0A6E) e0a9ae ੯ GURMUKHI DIGIT NINE (U+0A6F) e0a9af à©° GURMUKHI TIPPI (U+0A70) e0a9b0 ੱ GURMUKHI ADDAK (U+0A71) e0a9b1 ੲ GURMUKHI IRI (U+0A72) e0a9b2 ੳ GURMUKHI URA (U+0A73) e0a9b3 à©´ GURMUKHI EK ONKAR (U+0A74) e0a9b4 ੵ GURMUKHI SIGN YAKASH (U+0A75) e0a9b5 ઠGUJARATI SIGN CANDRABINDU (U+0A81) e0aa81 ં GUJARATI SIGN ANUSVARA (U+0A82) e0aa82 ઃ GUJARATI SIGN VISARGA (U+0A83) e0aa83 અ GUJARATI LETTER A (U+0A85) e0aa85 આ GUJARATI LETTER AA (U+0A86) e0aa86 ઇ GUJARATI LETTER I (U+0A87) e0aa87 ઈ GUJARATI LETTER II (U+0A88) e0aa88 ઉ GUJARATI LETTER U (U+0A89) e0aa89 ઊ GUJARATI LETTER UU (U+0A8A) e0aa8a ઋ GUJARATI LETTER VOCALIC R (U+0A8B) e0aa8b ઌ GUJARATI LETTER VOCALIC L (U+0A8C) e0aa8c ઠGUJARATI VOWEL CANDRA E (U+0A8D) e0aa8d ઠGUJARATI LETTER E (U+0A8F) e0aa8f ઠGUJARATI LETTER AI (U+0A90) e0aa90 ઑ GUJARATI VOWEL CANDRA O (U+0A91) e0aa91 ઓ GUJARATI LETTER O (U+0A93) e0aa93 ઔ GUJARATI LETTER AU (U+0A94) e0aa94 ક GUJARATI LETTER KA (U+0A95) e0aa95 ખ GUJARATI LETTER KHA (U+0A96) e0aa96 ગ GUJARATI LETTER GA (U+0A97) e0aa97 ઘ GUJARATI LETTER GHA (U+0A98) e0aa98 ઙ GUJARATI LETTER NGA (U+0A99) e0aa99 ચ GUJARATI LETTER CA (U+0A9A) e0aa9a છ GUJARATI LETTER CHA (U+0A9B) e0aa9b જ GUJARATI LETTER JA (U+0A9C) e0aa9c ઠGUJARATI LETTER JHA (U+0A9D) e0aa9d ઞ GUJARATI LETTER NYA (U+0A9E) e0aa9e ટ GUJARATI LETTER TTA (U+0A9F) e0aa9f ઠ GUJARATI LETTER TTHA (U+0AA0) e0aaa0 ડ GUJARATI LETTER DDA (U+0AA1) e0aaa1 ઢ GUJARATI LETTER DDHA (U+0AA2) e0aaa2 ણ GUJARATI LETTER NNA (U+0AA3) e0aaa3 ત GUJARATI LETTER TA (U+0AA4) e0aaa4 થ GUJARATI LETTER THA (U+0AA5) e0aaa5 દ GUJARATI LETTER DA (U+0AA6) e0aaa6 ધ GUJARATI LETTER DHA (U+0AA7) e0aaa7 ન GUJARATI LETTER NA (U+0AA8) e0aaa8 પ GUJARATI LETTER PA (U+0AAA) e0aaaa ફ GUJARATI LETTER PHA (U+0AAB) e0aaab બ GUJARATI LETTER BA (U+0AAC) e0aaac ભ GUJARATI LETTER BHA (U+0AAD) e0aaad મ GUJARATI LETTER MA (U+0AAE) e0aaae ય GUJARATI LETTER YA (U+0AAF) e0aaaf ર GUJARATI LETTER RA (U+0AB0) e0aab0 લ GUJARATI LETTER LA (U+0AB2) e0aab2 ળ GUJARATI LETTER LLA (U+0AB3) e0aab3 વ GUJARATI LETTER VA (U+0AB5) e0aab5 શ GUJARATI LETTER SHA (U+0AB6) e0aab6 ષ GUJARATI LETTER SSA (U+0AB7) e0aab7 સ GUJARATI LETTER SA (U+0AB8) e0aab8 હ GUJARATI LETTER HA (U+0AB9) e0aab9 ઼ GUJARATI SIGN NUKTA (U+0ABC) e0aabc ઽ GUJARATI SIGN AVAGRAHA (U+0ABD) e0aabd ા GUJARATI VOWEL SIGN AA (U+0ABE) e0aabe િ GUJARATI VOWEL SIGN I (U+0ABF) e0aabf à«€ GUJARATI VOWEL SIGN II (U+0AC0) e0ab80 à« GUJARATI VOWEL SIGN U (U+0AC1) e0ab81 à«‚ GUJARATI VOWEL SIGN UU (U+0AC2) e0ab82 ૃ GUJARATI VOWEL SIGN VOCALIC R (U+0AC3) e0ab83 à«„ GUJARATI VOWEL SIGN VOCALIC RR (U+0AC4) e0ab84 à«… GUJARATI VOWEL SIGN CANDRA E (U+0AC5) e0ab85 ે GUJARATI VOWEL SIGN E (U+0AC7) e0ab87 ૈ GUJARATI VOWEL SIGN AI (U+0AC8) e0ab88 ૉ GUJARATI VOWEL SIGN CANDRA O (U+0AC9) e0ab89 à«‹ GUJARATI VOWEL SIGN O (U+0ACB) e0ab8b ૌ GUJARATI VOWEL SIGN AU (U+0ACC) e0ab8c à« GUJARATI SIGN VIRAMA (U+0ACD) e0ab8d à« GUJARATI OM (U+0AD0) e0ab90 à«  GUJARATI LETTER VOCALIC RR (U+0AE0) e0aba0 à«¡ GUJARATI LETTER VOCALIC LL (U+0AE1) e0aba1 à«¢ GUJARATI VOWEL SIGN VOCALIC L (U+0AE2) e0aba2 à«£ GUJARATI VOWEL SIGN VOCALIC LL (U+0AE3) e0aba3 ૦ GUJARATI DIGIT ZERO (U+0AE6) e0aba6 à«§ GUJARATI DIGIT ONE (U+0AE7) e0aba7 ૨ GUJARATI DIGIT TWO (U+0AE8) e0aba8 à«© GUJARATI DIGIT THREE (U+0AE9) e0aba9 ૪ GUJARATI DIGIT FOUR (U+0AEA) e0abaa à«« GUJARATI DIGIT FIVE (U+0AEB) e0abab ૬ GUJARATI DIGIT SIX (U+0AEC) e0abac à«­ GUJARATI DIGIT SEVEN (U+0AED) e0abad à«® GUJARATI DIGIT EIGHT (U+0AEE) e0abae ૯ GUJARATI DIGIT NINE (U+0AEF) e0abaf ૱ GUJARATI RUPEE SIGN (U+0AF1) e0abb1 ଠORIYA SIGN CANDRABINDU (U+0B01) e0ac81 ଂ ORIYA SIGN ANUSVARA (U+0B02) e0ac82 ଃ ORIYA SIGN VISARGA (U+0B03) e0ac83 ଅ ORIYA LETTER A (U+0B05) e0ac85 ଆ ORIYA LETTER AA (U+0B06) e0ac86 ଇ ORIYA LETTER I (U+0B07) e0ac87 ଈ ORIYA LETTER II (U+0B08) e0ac88 ଉ ORIYA LETTER U (U+0B09) e0ac89 ଊ ORIYA LETTER UU (U+0B0A) e0ac8a ଋ ORIYA LETTER VOCALIC R (U+0B0B) e0ac8b ଌ ORIYA LETTER VOCALIC L (U+0B0C) e0ac8c ଠORIYA LETTER E (U+0B0F) e0ac8f ଠORIYA LETTER AI (U+0B10) e0ac90 ଓ ORIYA LETTER O (U+0B13) e0ac93 ଔ ORIYA LETTER AU (U+0B14) e0ac94 କ ORIYA LETTER KA (U+0B15) e0ac95 ଖ ORIYA LETTER KHA (U+0B16) e0ac96 ଗ ORIYA LETTER GA (U+0B17) e0ac97 ଘ ORIYA LETTER GHA (U+0B18) e0ac98 ଙ ORIYA LETTER NGA (U+0B19) e0ac99 ଚ ORIYA LETTER CA (U+0B1A) e0ac9a ଛ ORIYA LETTER CHA (U+0B1B) e0ac9b ଜ ORIYA LETTER JA (U+0B1C) e0ac9c ଠORIYA LETTER JHA (U+0B1D) e0ac9d ଞ ORIYA LETTER NYA (U+0B1E) e0ac9e ଟ ORIYA LETTER TTA (U+0B1F) e0ac9f ଠ ORIYA LETTER TTHA (U+0B20) e0aca0 ଡ ORIYA LETTER DDA (U+0B21) e0aca1 ଢ ORIYA LETTER DDHA (U+0B22) e0aca2 ଣ ORIYA LETTER NNA (U+0B23) e0aca3 ତ ORIYA LETTER TA (U+0B24) e0aca4 ଥ ORIYA LETTER THA (U+0B25) e0aca5 ଦ ORIYA LETTER DA (U+0B26) e0aca6 ଧ ORIYA LETTER DHA (U+0B27) e0aca7 ନ ORIYA LETTER NA (U+0B28) e0aca8 ପ ORIYA LETTER PA (U+0B2A) e0acaa ଫ ORIYA LETTER PHA (U+0B2B) e0acab ବ ORIYA LETTER BA (U+0B2C) e0acac ଭ ORIYA LETTER BHA (U+0B2D) e0acad ମ ORIYA LETTER MA (U+0B2E) e0acae ଯ ORIYA LETTER YA (U+0B2F) e0acaf ର ORIYA LETTER RA (U+0B30) e0acb0 ଲ ORIYA LETTER LA (U+0B32) e0acb2 ଳ ORIYA LETTER LLA (U+0B33) e0acb3 ଵ ORIYA LETTER VA (U+0B35) e0acb5 ଶ ORIYA LETTER SHA (U+0B36) e0acb6 ଷ ORIYA LETTER SSA (U+0B37) e0acb7 ସ ORIYA LETTER SA (U+0B38) e0acb8 ହ ORIYA LETTER HA (U+0B39) e0acb9 ଼ ORIYA SIGN NUKTA (U+0B3C) e0acbc ଽ ORIYA SIGN AVAGRAHA (U+0B3D) e0acbd ା ORIYA VOWEL SIGN AA (U+0B3E) e0acbe ି ORIYA VOWEL SIGN I (U+0B3F) e0acbf à­€ ORIYA VOWEL SIGN II (U+0B40) e0ad80 à­ ORIYA VOWEL SIGN U (U+0B41) e0ad81 à­‚ ORIYA VOWEL SIGN UU (U+0B42) e0ad82 à­ƒ ORIYA VOWEL SIGN VOCALIC R (U+0B43) e0ad83 à­„ ORIYA VOWEL SIGN VOCALIC RR (U+0B44) e0ad84 à­‡ ORIYA VOWEL SIGN E (U+0B47) e0ad87 à­ˆ ORIYA VOWEL SIGN AI (U+0B48) e0ad88 à­‹ ORIYA VOWEL SIGN O (U+0B4B) e0ad8b à­Œ ORIYA VOWEL SIGN AU (U+0B4C) e0ad8c à­ ORIYA SIGN VIRAMA (U+0B4D) e0ad8d à­– ORIYA AI LENGTH MARK (U+0B56) e0ad96 à­— ORIYA AU LENGTH MARK (U+0B57) e0ad97 à­œ ORIYA LETTER RRA (U+0B5C) e0ad9c à­ ORIYA LETTER RHA (U+0B5D) e0ad9d à­Ÿ ORIYA LETTER YYA (U+0B5F) e0ad9f à­  ORIYA LETTER VOCALIC RR (U+0B60) e0ada0 à­¡ ORIYA LETTER VOCALIC LL (U+0B61) e0ada1 à­¢ ORIYA VOWEL SIGN VOCALIC L (U+0B62) e0ada2 à­£ ORIYA VOWEL SIGN VOCALIC LL (U+0B63) e0ada3 à­¦ ORIYA DIGIT ZERO (U+0B66) e0ada6 à­§ ORIYA DIGIT ONE (U+0B67) e0ada7 à­¨ ORIYA DIGIT TWO (U+0B68) e0ada8 à­© ORIYA DIGIT THREE (U+0B69) e0ada9 à­ª ORIYA DIGIT FOUR (U+0B6A) e0adaa à­« ORIYA DIGIT FIVE (U+0B6B) e0adab à­¬ ORIYA DIGIT SIX (U+0B6C) e0adac à­­ ORIYA DIGIT SEVEN (U+0B6D) e0adad à­® ORIYA DIGIT EIGHT (U+0B6E) e0adae à­¯ ORIYA DIGIT NINE (U+0B6F) e0adaf à­° ORIYA ISSHAR (U+0B70) e0adb0 à­± ORIYA LETTER WA (U+0B71) e0adb1 à­² ORIYA FRACTION ONE QUARTER (U+0B72) e0adb2 à­³ ORIYA FRACTION ONE HALF (U+0B73) e0adb3 à­´ ORIYA FRACTION THREE QUARTERS (U+0B74) e0adb4 à­µ ORIYA FRACTION ONE SIXTEENTH (U+0B75) e0adb5 à­¶ ORIYA FRACTION ONE EIGHTH (U+0B76) e0adb6 à­· ORIYA FRACTION THREE SIXTEENTHS (U+0B77) e0adb7 ஂ TAMIL SIGN ANUSVARA (U+0B82) e0ae82 ஃ TAMIL SIGN VISARGA (U+0B83) e0ae83 à®… TAMIL LETTER A (U+0B85) e0ae85 ஆ TAMIL LETTER AA (U+0B86) e0ae86 இ TAMIL LETTER I (U+0B87) e0ae87 ஈ TAMIL LETTER II (U+0B88) e0ae88 உ TAMIL LETTER U (U+0B89) e0ae89 ஊ TAMIL LETTER UU (U+0B8A) e0ae8a எ TAMIL LETTER E (U+0B8E) e0ae8e à® TAMIL LETTER EE (U+0B8F) e0ae8f à® TAMIL LETTER AI (U+0B90) e0ae90 à®’ TAMIL LETTER O (U+0B92) e0ae92 ஓ TAMIL LETTER OO (U+0B93) e0ae93 à®” TAMIL LETTER AU (U+0B94) e0ae94 க TAMIL LETTER KA (U+0B95) e0ae95 à®™ TAMIL LETTER NGA (U+0B99) e0ae99 ச TAMIL LETTER CA (U+0B9A) e0ae9a ஜ TAMIL LETTER JA (U+0B9C) e0ae9c ஞ TAMIL LETTER NYA (U+0B9E) e0ae9e ட TAMIL LETTER TTA (U+0B9F) e0ae9f ண TAMIL LETTER NNA (U+0BA3) e0aea3 த TAMIL LETTER TA (U+0BA4) e0aea4 ந TAMIL LETTER NA (U+0BA8) e0aea8 ன TAMIL LETTER NNNA (U+0BA9) e0aea9 ப TAMIL LETTER PA (U+0BAA) e0aeaa à®® TAMIL LETTER MA (U+0BAE) e0aeae ய TAMIL LETTER YA (U+0BAF) e0aeaf à®° TAMIL LETTER RA (U+0BB0) e0aeb0 à®± TAMIL LETTER RRA (U+0BB1) e0aeb1 ல TAMIL LETTER LA (U+0BB2) e0aeb2 ள TAMIL LETTER LLA (U+0BB3) e0aeb3 à®´ TAMIL LETTER LLLA (U+0BB4) e0aeb4 வ TAMIL LETTER VA (U+0BB5) e0aeb5 à®¶ TAMIL LETTER SHA (U+0BB6) e0aeb6 à®· TAMIL LETTER SSA (U+0BB7) e0aeb7 ஸ TAMIL LETTER SA (U+0BB8) e0aeb8 ஹ TAMIL LETTER HA (U+0BB9) e0aeb9 ா TAMIL VOWEL SIGN AA (U+0BBE) e0aebe ி TAMIL VOWEL SIGN I (U+0BBF) e0aebf ீ TAMIL VOWEL SIGN II (U+0BC0) e0af80 ௠TAMIL VOWEL SIGN U (U+0BC1) e0af81 ூ TAMIL VOWEL SIGN UU (U+0BC2) e0af82 ெ TAMIL VOWEL SIGN E (U+0BC6) e0af86 ே TAMIL VOWEL SIGN EE (U+0BC7) e0af87 ை TAMIL VOWEL SIGN AI (U+0BC8) e0af88 ொ TAMIL VOWEL SIGN O (U+0BCA) e0af8a ோ TAMIL VOWEL SIGN OO (U+0BCB) e0af8b ௌ TAMIL VOWEL SIGN AU (U+0BCC) e0af8c ௠TAMIL SIGN VIRAMA (U+0BCD) e0af8d ௠TAMIL OM (U+0BD0) e0af90 ௗ TAMIL AU LENGTH MARK (U+0BD7) e0af97 ௦ TAMIL DIGIT ZERO (U+0BE6) e0afa6 ௧ TAMIL DIGIT ONE (U+0BE7) e0afa7 ௨ TAMIL DIGIT TWO (U+0BE8) e0afa8 ௩ TAMIL DIGIT THREE (U+0BE9) e0afa9 ௪ TAMIL DIGIT FOUR (U+0BEA) e0afaa ௫ TAMIL DIGIT FIVE (U+0BEB) e0afab ௬ TAMIL DIGIT SIX (U+0BEC) e0afac ௭ TAMIL DIGIT SEVEN (U+0BED) e0afad ௮ TAMIL DIGIT EIGHT (U+0BEE) e0afae ௯ TAMIL DIGIT NINE (U+0BEF) e0afaf ௰ TAMIL NUMBER TEN (U+0BF0) e0afb0 ௱ TAMIL NUMBER ONE HUNDRED (U+0BF1) e0afb1 ௲ TAMIL NUMBER ONE THOUSAND (U+0BF2) e0afb2 ௳ TAMIL DAY SIGN (U+0BF3) e0afb3 ௴ TAMIL MONTH SIGN (U+0BF4) e0afb4 ௵ TAMIL YEAR SIGN (U+0BF5) e0afb5 ௶ TAMIL DEBIT SIGN (U+0BF6) e0afb6 ௷ TAMIL CREDIT SIGN (U+0BF7) e0afb7 ௸ TAMIL AS ABOVE SIGN (U+0BF8) e0afb8 ௹ TAMIL RUPEE SIGN (U+0BF9) e0afb9 ௺ TAMIL NUMBER SIGN (U+0BFA) e0afba à° TELUGU SIGN CANDRABINDU (U+0C01) e0b081 à°‚ TELUGU SIGN ANUSVARA (U+0C02) e0b082 à°ƒ TELUGU SIGN VISARGA (U+0C03) e0b083 à°… TELUGU LETTER A (U+0C05) e0b085 à°† TELUGU LETTER AA (U+0C06) e0b086 à°‡ TELUGU LETTER I (U+0C07) e0b087 à°ˆ TELUGU LETTER II (U+0C08) e0b088 à°‰ TELUGU LETTER U (U+0C09) e0b089 à°Š TELUGU LETTER UU (U+0C0A) e0b08a à°‹ TELUGU LETTER VOCALIC R (U+0C0B) e0b08b à°Œ TELUGU LETTER VOCALIC L (U+0C0C) e0b08c à°Ž TELUGU LETTER E (U+0C0E) e0b08e à° TELUGU LETTER EE (U+0C0F) e0b08f à° TELUGU LETTER AI (U+0C10) e0b090 à°’ TELUGU LETTER O (U+0C12) e0b092 à°“ TELUGU LETTER OO (U+0C13) e0b093 à°” TELUGU LETTER AU (U+0C14) e0b094 à°• TELUGU LETTER KA (U+0C15) e0b095 à°– TELUGU LETTER KHA (U+0C16) e0b096 à°— TELUGU LETTER GA (U+0C17) e0b097 à°˜ TELUGU LETTER GHA (U+0C18) e0b098 à°™ TELUGU LETTER NGA (U+0C19) e0b099 à°š TELUGU LETTER CA (U+0C1A) e0b09a à°› TELUGU LETTER CHA (U+0C1B) e0b09b à°œ TELUGU LETTER JA (U+0C1C) e0b09c à° TELUGU LETTER JHA (U+0C1D) e0b09d à°ž TELUGU LETTER NYA (U+0C1E) e0b09e à°Ÿ TELUGU LETTER TTA (U+0C1F) e0b09f à°  TELUGU LETTER TTHA (U+0C20) e0b0a0 à°¡ TELUGU LETTER DDA (U+0C21) e0b0a1 à°¢ TELUGU LETTER DDHA (U+0C22) e0b0a2 à°£ TELUGU LETTER NNA (U+0C23) e0b0a3 à°¤ TELUGU LETTER TA (U+0C24) e0b0a4 à°¥ TELUGU LETTER THA (U+0C25) e0b0a5 à°¦ TELUGU LETTER DA (U+0C26) e0b0a6 à°§ TELUGU LETTER DHA (U+0C27) e0b0a7 à°¨ TELUGU LETTER NA (U+0C28) e0b0a8 à°ª TELUGU LETTER PA (U+0C2A) e0b0aa à°« TELUGU LETTER PHA (U+0C2B) e0b0ab à°¬ TELUGU LETTER BA (U+0C2C) e0b0ac à°­ TELUGU LETTER BHA (U+0C2D) e0b0ad à°® TELUGU LETTER MA (U+0C2E) e0b0ae à°¯ TELUGU LETTER YA (U+0C2F) e0b0af à°° TELUGU LETTER RA (U+0C30) e0b0b0 à°± TELUGU LETTER RRA (U+0C31) e0b0b1 à°² TELUGU LETTER LA (U+0C32) e0b0b2 à°³ TELUGU LETTER LLA (U+0C33) e0b0b3 à°µ TELUGU LETTER VA (U+0C35) e0b0b5 à°¶ TELUGU LETTER SHA (U+0C36) e0b0b6 à°· TELUGU LETTER SSA (U+0C37) e0b0b7 à°¸ TELUGU LETTER SA (U+0C38) e0b0b8 à°¹ TELUGU LETTER HA (U+0C39) e0b0b9 à°½ TELUGU SIGN AVAGRAHA (U+0C3D) e0b0bd à°¾ TELUGU VOWEL SIGN AA (U+0C3E) e0b0be à°¿ TELUGU VOWEL SIGN I (U+0C3F) e0b0bf à±€ TELUGU VOWEL SIGN II (U+0C40) e0b180 à± TELUGU VOWEL SIGN U (U+0C41) e0b181 ూ TELUGU VOWEL SIGN UU (U+0C42) e0b182 ృ TELUGU VOWEL SIGN VOCALIC R (U+0C43) e0b183 ౄ TELUGU VOWEL SIGN VOCALIC RR (U+0C44) e0b184 ె TELUGU VOWEL SIGN E (U+0C46) e0b186 ే TELUGU VOWEL SIGN EE (U+0C47) e0b187 ై TELUGU VOWEL SIGN AI (U+0C48) e0b188 ొ TELUGU VOWEL SIGN O (U+0C4A) e0b18a ో TELUGU VOWEL SIGN OO (U+0C4B) e0b18b ౌ TELUGU VOWEL SIGN AU (U+0C4C) e0b18c à± TELUGU SIGN VIRAMA (U+0C4D) e0b18d ౕ TELUGU LENGTH MARK (U+0C55) e0b195 à±– TELUGU AI LENGTH MARK (U+0C56) e0b196 ౘ TELUGU LETTER TSA (U+0C58) e0b198 à±™ TELUGU LETTER DZA (U+0C59) e0b199 à±  TELUGU LETTER VOCALIC RR (U+0C60) e0b1a0 ౡ TELUGU LETTER VOCALIC LL (U+0C61) e0b1a1 à±¢ TELUGU VOWEL SIGN VOCALIC L (U+0C62) e0b1a2 à±£ TELUGU VOWEL SIGN VOCALIC LL (U+0C63) e0b1a3 ౦ TELUGU DIGIT ZERO (U+0C66) e0b1a6 à±§ TELUGU DIGIT ONE (U+0C67) e0b1a7 ౨ TELUGU DIGIT TWO (U+0C68) e0b1a8 ౩ TELUGU DIGIT THREE (U+0C69) e0b1a9 ౪ TELUGU DIGIT FOUR (U+0C6A) e0b1aa ౫ TELUGU DIGIT FIVE (U+0C6B) e0b1ab ౬ TELUGU DIGIT SIX (U+0C6C) e0b1ac à±­ TELUGU DIGIT SEVEN (U+0C6D) e0b1ad à±® TELUGU DIGIT EIGHT (U+0C6E) e0b1ae ౯ TELUGU DIGIT NINE (U+0C6F) e0b1af ౸ TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR (U+0C78) e0b1b8 à±¹ TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR (U+0C79) e0b1b9 ౺ TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR (U+0C7A) e0b1ba à±» TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR (U+0C7B) e0b1bb à±¼ TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR (U+0C7C) e0b1bc à±½ TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR (U+0C7D) e0b1bd à±¾ TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR (U+0C7E) e0b1be ౿ TELUGU SIGN TUUMU (U+0C7F) e0b1bf ಂ KANNADA SIGN ANUSVARA (U+0C82) e0b282 ಃ KANNADA SIGN VISARGA (U+0C83) e0b283 ಅ KANNADA LETTER A (U+0C85) e0b285 ಆ KANNADA LETTER AA (U+0C86) e0b286 ಇ KANNADA LETTER I (U+0C87) e0b287 ಈ KANNADA LETTER II (U+0C88) e0b288 ಉ KANNADA LETTER U (U+0C89) e0b289 ಊ KANNADA LETTER UU (U+0C8A) e0b28a ಋ KANNADA LETTER VOCALIC R (U+0C8B) e0b28b ಌ KANNADA LETTER VOCALIC L (U+0C8C) e0b28c ಎ KANNADA LETTER E (U+0C8E) e0b28e ಠKANNADA LETTER EE (U+0C8F) e0b28f ಠKANNADA LETTER AI (U+0C90) e0b290 ಒ KANNADA LETTER O (U+0C92) e0b292 ಓ KANNADA LETTER OO (U+0C93) e0b293 ಔ KANNADA LETTER AU (U+0C94) e0b294 ಕ KANNADA LETTER KA (U+0C95) e0b295 ಖ KANNADA LETTER KHA (U+0C96) e0b296 ಗ KANNADA LETTER GA (U+0C97) e0b297 ಘ KANNADA LETTER GHA (U+0C98) e0b298 ಙ KANNADA LETTER NGA (U+0C99) e0b299 ಚ KANNADA LETTER CA (U+0C9A) e0b29a ಛ KANNADA LETTER CHA (U+0C9B) e0b29b ಜ KANNADA LETTER JA (U+0C9C) e0b29c ಠKANNADA LETTER JHA (U+0C9D) e0b29d ಞ KANNADA LETTER NYA (U+0C9E) e0b29e ಟ KANNADA LETTER TTA (U+0C9F) e0b29f ಠ KANNADA LETTER TTHA (U+0CA0) e0b2a0 ಡ KANNADA LETTER DDA (U+0CA1) e0b2a1 ಢ KANNADA LETTER DDHA (U+0CA2) e0b2a2 ಣ KANNADA LETTER NNA (U+0CA3) e0b2a3 ತ KANNADA LETTER TA (U+0CA4) e0b2a4 ಥ KANNADA LETTER THA (U+0CA5) e0b2a5 ದ KANNADA LETTER DA (U+0CA6) e0b2a6 ಧ KANNADA LETTER DHA (U+0CA7) e0b2a7 ನ KANNADA LETTER NA (U+0CA8) e0b2a8 ಪ KANNADA LETTER PA (U+0CAA) e0b2aa ಫ KANNADA LETTER PHA (U+0CAB) e0b2ab ಬ KANNADA LETTER BA (U+0CAC) e0b2ac ಭ KANNADA LETTER BHA (U+0CAD) e0b2ad ಮ KANNADA LETTER MA (U+0CAE) e0b2ae ಯ KANNADA LETTER YA (U+0CAF) e0b2af ರ KANNADA LETTER RA (U+0CB0) e0b2b0 ಱ KANNADA LETTER RRA (U+0CB1) e0b2b1 ಲ KANNADA LETTER LA (U+0CB2) e0b2b2 ಳ KANNADA LETTER LLA (U+0CB3) e0b2b3 ವ KANNADA LETTER VA (U+0CB5) e0b2b5 ಶ KANNADA LETTER SHA (U+0CB6) e0b2b6 ಷ KANNADA LETTER SSA (U+0CB7) e0b2b7 ಸ KANNADA LETTER SA (U+0CB8) e0b2b8 ಹ KANNADA LETTER HA (U+0CB9) e0b2b9 ಼ KANNADA SIGN NUKTA (U+0CBC) e0b2bc ಽ KANNADA SIGN AVAGRAHA (U+0CBD) e0b2bd ಾ KANNADA VOWEL SIGN AA (U+0CBE) e0b2be ಿ KANNADA VOWEL SIGN I (U+0CBF) e0b2bf à³€ KANNADA VOWEL SIGN II (U+0CC0) e0b380 à³ KANNADA VOWEL SIGN U (U+0CC1) e0b381 ೂ KANNADA VOWEL SIGN UU (U+0CC2) e0b382 ೃ KANNADA VOWEL SIGN VOCALIC R (U+0CC3) e0b383 ೄ KANNADA VOWEL SIGN VOCALIC RR (U+0CC4) e0b384 ೆ KANNADA VOWEL SIGN E (U+0CC6) e0b386 ೇ KANNADA VOWEL SIGN EE (U+0CC7) e0b387 ೈ KANNADA VOWEL SIGN AI (U+0CC8) e0b388 ೊ KANNADA VOWEL SIGN O (U+0CCA) e0b38a ೋ KANNADA VOWEL SIGN OO (U+0CCB) e0b38b ೌ KANNADA VOWEL SIGN AU (U+0CCC) e0b38c à³ KANNADA SIGN VIRAMA (U+0CCD) e0b38d ೕ KANNADA LENGTH MARK (U+0CD5) e0b395 à³– KANNADA AI LENGTH MARK (U+0CD6) e0b396 ೞ KANNADA LETTER FA (U+0CDE) e0b39e à³  KANNADA LETTER VOCALIC RR (U+0CE0) e0b3a0 ೡ KANNADA LETTER VOCALIC LL (U+0CE1) e0b3a1 à³¢ KANNADA VOWEL SIGN VOCALIC L (U+0CE2) e0b3a2 à³£ KANNADA VOWEL SIGN VOCALIC LL (U+0CE3) e0b3a3 ೦ KANNADA DIGIT ZERO (U+0CE6) e0b3a6 à³§ KANNADA DIGIT ONE (U+0CE7) e0b3a7 ೨ KANNADA DIGIT TWO (U+0CE8) e0b3a8 ೩ KANNADA DIGIT THREE (U+0CE9) e0b3a9 ೪ KANNADA DIGIT FOUR (U+0CEA) e0b3aa ೫ KANNADA DIGIT FIVE (U+0CEB) e0b3ab ೬ KANNADA DIGIT SIX (U+0CEC) e0b3ac à³­ KANNADA DIGIT SEVEN (U+0CED) e0b3ad à³® KANNADA DIGIT EIGHT (U+0CEE) e0b3ae ೯ KANNADA DIGIT NINE (U+0CEF) e0b3af à³± KANNADA SIGN JIHVAMULIYA (U+0CF1) e0b3b1 à³² KANNADA SIGN UPADHMANIYA (U+0CF2) e0b3b2 à´‚ MALAYALAM SIGN ANUSVARA (U+0D02) e0b482 à´ƒ MALAYALAM SIGN VISARGA (U+0D03) e0b483 à´… MALAYALAM LETTER A (U+0D05) e0b485 à´† MALAYALAM LETTER AA (U+0D06) e0b486 à´‡ MALAYALAM LETTER I (U+0D07) e0b487 à´ˆ MALAYALAM LETTER II (U+0D08) e0b488 à´‰ MALAYALAM LETTER U (U+0D09) e0b489 à´Š MALAYALAM LETTER UU (U+0D0A) e0b48a à´‹ MALAYALAM LETTER VOCALIC R (U+0D0B) e0b48b à´Œ MALAYALAM LETTER VOCALIC L (U+0D0C) e0b48c à´Ž MALAYALAM LETTER E (U+0D0E) e0b48e à´ MALAYALAM LETTER EE (U+0D0F) e0b48f à´ MALAYALAM LETTER AI (U+0D10) e0b490 à´’ MALAYALAM LETTER O (U+0D12) e0b492 à´“ MALAYALAM LETTER OO (U+0D13) e0b493 à´” MALAYALAM LETTER AU (U+0D14) e0b494 à´• MALAYALAM LETTER KA (U+0D15) e0b495 à´– MALAYALAM LETTER KHA (U+0D16) e0b496 à´— MALAYALAM LETTER GA (U+0D17) e0b497 à´˜ MALAYALAM LETTER GHA (U+0D18) e0b498 à´™ MALAYALAM LETTER NGA (U+0D19) e0b499 à´š MALAYALAM LETTER CA (U+0D1A) e0b49a à´› MALAYALAM LETTER CHA (U+0D1B) e0b49b à´œ MALAYALAM LETTER JA (U+0D1C) e0b49c à´ MALAYALAM LETTER JHA (U+0D1D) e0b49d à´ž MALAYALAM LETTER NYA (U+0D1E) e0b49e à´Ÿ MALAYALAM LETTER TTA (U+0D1F) e0b49f à´  MALAYALAM LETTER TTHA (U+0D20) e0b4a0 à´¡ MALAYALAM LETTER DDA (U+0D21) e0b4a1 à´¢ MALAYALAM LETTER DDHA (U+0D22) e0b4a2 à´£ MALAYALAM LETTER NNA (U+0D23) e0b4a3 à´¤ MALAYALAM LETTER TA (U+0D24) e0b4a4 à´¥ MALAYALAM LETTER THA (U+0D25) e0b4a5 à´¦ MALAYALAM LETTER DA (U+0D26) e0b4a6 à´§ MALAYALAM LETTER DHA (U+0D27) e0b4a7 à´¨ MALAYALAM LETTER NA (U+0D28) e0b4a8 à´© MALAYALAM LETTER NNNA (U+0D29) e0b4a9 à´ª MALAYALAM LETTER PA (U+0D2A) e0b4aa à´« MALAYALAM LETTER PHA (U+0D2B) e0b4ab à´¬ MALAYALAM LETTER BA (U+0D2C) e0b4ac à´­ MALAYALAM LETTER BHA (U+0D2D) e0b4ad à´® MALAYALAM LETTER MA (U+0D2E) e0b4ae à´¯ MALAYALAM LETTER YA (U+0D2F) e0b4af à´° MALAYALAM LETTER RA (U+0D30) e0b4b0 à´± MALAYALAM LETTER RRA (U+0D31) e0b4b1 à´² MALAYALAM LETTER LA (U+0D32) e0b4b2 à´³ MALAYALAM LETTER LLA (U+0D33) e0b4b3 à´´ MALAYALAM LETTER LLLA (U+0D34) e0b4b4 à´µ MALAYALAM LETTER VA (U+0D35) e0b4b5 à´¶ MALAYALAM LETTER SHA (U+0D36) e0b4b6 à´· MALAYALAM LETTER SSA (U+0D37) e0b4b7 à´¸ MALAYALAM LETTER SA (U+0D38) e0b4b8 à´¹ MALAYALAM LETTER HA (U+0D39) e0b4b9 à´º MALAYALAM LETTER TTTA (U+0D3A) e0b4ba à´½ MALAYALAM SIGN AVAGRAHA (U+0D3D) e0b4bd à´¾ MALAYALAM VOWEL SIGN AA (U+0D3E) e0b4be à´¿ MALAYALAM VOWEL SIGN I (U+0D3F) e0b4bf ീ MALAYALAM VOWEL SIGN II (U+0D40) e0b580 ൠMALAYALAM VOWEL SIGN U (U+0D41) e0b581 ൂ MALAYALAM VOWEL SIGN UU (U+0D42) e0b582 ൃ MALAYALAM VOWEL SIGN VOCALIC R (U+0D43) e0b583 ൄ MALAYALAM VOWEL SIGN VOCALIC RR (U+0D44) e0b584 െ MALAYALAM VOWEL SIGN E (U+0D46) e0b586 േ MALAYALAM VOWEL SIGN EE (U+0D47) e0b587 ൈ MALAYALAM VOWEL SIGN AI (U+0D48) e0b588 ൊ MALAYALAM VOWEL SIGN O (U+0D4A) e0b58a ോ MALAYALAM VOWEL SIGN OO (U+0D4B) e0b58b ൌ MALAYALAM VOWEL SIGN AU (U+0D4C) e0b58c ൠMALAYALAM SIGN VIRAMA (U+0D4D) e0b58d ൎ MALAYALAM LETTER DOT REPH (U+0D4E) e0b58e ൗ MALAYALAM AU LENGTH MARK (U+0D57) e0b597 ൠ MALAYALAM LETTER VOCALIC RR (U+0D60) e0b5a0 ൡ MALAYALAM LETTER VOCALIC LL (U+0D61) e0b5a1 ൢ MALAYALAM VOWEL SIGN VOCALIC L (U+0D62) e0b5a2 ൣ MALAYALAM VOWEL SIGN VOCALIC LL (U+0D63) e0b5a3 ൦ MALAYALAM DIGIT ZERO (U+0D66) e0b5a6 ൧ MALAYALAM DIGIT ONE (U+0D67) e0b5a7 ൨ MALAYALAM DIGIT TWO (U+0D68) e0b5a8 ൩ MALAYALAM DIGIT THREE (U+0D69) e0b5a9 ൪ MALAYALAM DIGIT FOUR (U+0D6A) e0b5aa ൫ MALAYALAM DIGIT FIVE (U+0D6B) e0b5ab ൬ MALAYALAM DIGIT SIX (U+0D6C) e0b5ac ൭ MALAYALAM DIGIT SEVEN (U+0D6D) e0b5ad ൮ MALAYALAM DIGIT EIGHT (U+0D6E) e0b5ae ൯ MALAYALAM DIGIT NINE (U+0D6F) e0b5af ൰ MALAYALAM NUMBER TEN (U+0D70) e0b5b0 ൱ MALAYALAM NUMBER ONE HUNDRED (U+0D71) e0b5b1 ൲ MALAYALAM NUMBER ONE THOUSAND (U+0D72) e0b5b2 ൳ MALAYALAM FRACTION ONE QUARTER (U+0D73) e0b5b3 ൴ MALAYALAM FRACTION ONE HALF (U+0D74) e0b5b4 ൵ MALAYALAM FRACTION THREE QUARTERS (U+0D75) e0b5b5 ൹ MALAYALAM DATE MARK (U+0D79) e0b5b9 ൺ MALAYALAM LETTER CHILLU NN (U+0D7A) e0b5ba ൻ MALAYALAM LETTER CHILLU N (U+0D7B) e0b5bb ർ MALAYALAM LETTER CHILLU RR (U+0D7C) e0b5bc ൽ MALAYALAM LETTER CHILLU L (U+0D7D) e0b5bd ൾ MALAYALAM LETTER CHILLU LL (U+0D7E) e0b5be ൿ MALAYALAM LETTER CHILLU K (U+0D7F) e0b5bf à¶‚ SINHALA SIGN ANUSVARAYA (U+0D82) e0b682 ඃ SINHALA SIGN VISARGAYA (U+0D83) e0b683 à¶… SINHALA LETTER AYANNA (U+0D85) e0b685 ආ SINHALA LETTER AAYANNA (U+0D86) e0b686 ඇ SINHALA LETTER AEYANNA (U+0D87) e0b687 ඈ SINHALA LETTER AEEYANNA (U+0D88) e0b688 ඉ SINHALA LETTER IYANNA (U+0D89) e0b689 à¶Š SINHALA LETTER IIYANNA (U+0D8A) e0b68a à¶‹ SINHALA LETTER UYANNA (U+0D8B) e0b68b à¶Œ SINHALA LETTER UUYANNA (U+0D8C) e0b68c à¶ SINHALA LETTER IRUYANNA (U+0D8D) e0b68d à¶Ž SINHALA LETTER IRUUYANNA (U+0D8E) e0b68e à¶ SINHALA LETTER ILUYANNA (U+0D8F) e0b68f à¶ SINHALA LETTER ILUUYANNA (U+0D90) e0b690 à¶‘ SINHALA LETTER EYANNA (U+0D91) e0b691 à¶’ SINHALA LETTER EEYANNA (U+0D92) e0b692 à¶“ SINHALA LETTER AIYANNA (U+0D93) e0b693 à¶” SINHALA LETTER OYANNA (U+0D94) e0b694 à¶• SINHALA LETTER OOYANNA (U+0D95) e0b695 à¶– SINHALA LETTER AUYANNA (U+0D96) e0b696 à¶š SINHALA LETTER ALPAPRAANA KAYANNA (U+0D9A) e0b69a à¶› SINHALA LETTER MAHAAPRAANA KAYANNA (U+0D9B) e0b69b à¶œ SINHALA LETTER ALPAPRAANA GAYANNA (U+0D9C) e0b69c à¶ SINHALA LETTER MAHAAPRAANA GAYANNA (U+0D9D) e0b69d à¶ž SINHALA LETTER KANTAJA NAASIKYAYA (U+0D9E) e0b69e à¶Ÿ SINHALA LETTER SANYAKA GAYANNA (U+0D9F) e0b69f à¶  SINHALA LETTER ALPAPRAANA CAYANNA (U+0DA0) e0b6a0 à¶¡ SINHALA LETTER MAHAAPRAANA CAYANNA (U+0DA1) e0b6a1 à¶¢ SINHALA LETTER ALPAPRAANA JAYANNA (U+0DA2) e0b6a2 à¶£ SINHALA LETTER MAHAAPRAANA JAYANNA (U+0DA3) e0b6a3 ඤ SINHALA LETTER TAALUJA NAASIKYAYA (U+0DA4) e0b6a4 à¶¥ SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA (U+0DA5) e0b6a5 ඦ SINHALA LETTER SANYAKA JAYANNA (U+0DA6) e0b6a6 à¶§ SINHALA LETTER ALPAPRAANA TTAYANNA (U+0DA7) e0b6a7 ඨ SINHALA LETTER MAHAAPRAANA TTAYANNA (U+0DA8) e0b6a8 à¶© SINHALA LETTER ALPAPRAANA DDAYANNA (U+0DA9) e0b6a9 ඪ SINHALA LETTER MAHAAPRAANA DDAYANNA (U+0DAA) e0b6aa à¶« SINHALA LETTER MUURDHAJA NAYANNA (U+0DAB) e0b6ab ඬ SINHALA LETTER SANYAKA DDAYANNA (U+0DAC) e0b6ac à¶­ SINHALA LETTER ALPAPRAANA TAYANNA (U+0DAD) e0b6ad à¶® SINHALA LETTER MAHAAPRAANA TAYANNA (U+0DAE) e0b6ae ද SINHALA LETTER ALPAPRAANA DAYANNA (U+0DAF) e0b6af à¶° SINHALA LETTER MAHAAPRAANA DAYANNA (U+0DB0) e0b6b0 à¶± SINHALA LETTER DANTAJA NAYANNA (U+0DB1) e0b6b1 à¶³ SINHALA LETTER SANYAKA DAYANNA (U+0DB3) e0b6b3 à¶´ SINHALA LETTER ALPAPRAANA PAYANNA (U+0DB4) e0b6b4 à¶µ SINHALA LETTER MAHAAPRAANA PAYANNA (U+0DB5) e0b6b5 à¶¶ SINHALA LETTER ALPAPRAANA BAYANNA (U+0DB6) e0b6b6 à¶· SINHALA LETTER MAHAAPRAANA BAYANNA (U+0DB7) e0b6b7 ම SINHALA LETTER MAYANNA (U+0DB8) e0b6b8 à¶¹ SINHALA LETTER AMBA BAYANNA (U+0DB9) e0b6b9 ය SINHALA LETTER YAYANNA (U+0DBA) e0b6ba à¶» SINHALA LETTER RAYANNA (U+0DBB) e0b6bb à¶½ SINHALA LETTER DANTAJA LAYANNA (U+0DBD) e0b6bd à·€ SINHALA LETTER VAYANNA (U+0DC0) e0b780 à· SINHALA LETTER TAALUJA SAYANNA (U+0DC1) e0b781 à·‚ SINHALA LETTER MUURDHAJA SAYANNA (U+0DC2) e0b782 à·ƒ SINHALA LETTER DANTAJA SAYANNA (U+0DC3) e0b783 à·„ SINHALA LETTER HAYANNA (U+0DC4) e0b784 à·… SINHALA LETTER MUURDHAJA LAYANNA (U+0DC5) e0b785 à·† SINHALA LETTER FAYANNA (U+0DC6) e0b786 à·Š SINHALA SIGN AL-LAKUNA (U+0DCA) e0b78a à· SINHALA VOWEL SIGN AELA-PILLA (U+0DCF) e0b78f à· SINHALA VOWEL SIGN KETTI AEDA-PILLA (U+0DD0) e0b790 à·‘ SINHALA VOWEL SIGN DIGA AEDA-PILLA (U+0DD1) e0b791 à·’ SINHALA VOWEL SIGN KETTI IS-PILLA (U+0DD2) e0b792 à·“ SINHALA VOWEL SIGN DIGA IS-PILLA (U+0DD3) e0b793 à·” SINHALA VOWEL SIGN KETTI PAA-PILLA (U+0DD4) e0b794 à·– SINHALA VOWEL SIGN DIGA PAA-PILLA (U+0DD6) e0b796 à·˜ SINHALA VOWEL SIGN GAETTA-PILLA (U+0DD8) e0b798 à·™ SINHALA VOWEL SIGN KOMBUVA (U+0DD9) e0b799 à·š SINHALA VOWEL SIGN DIGA KOMBUVA (U+0DDA) e0b79a à·› SINHALA VOWEL SIGN KOMBU DEKA (U+0DDB) e0b79b à·œ SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA (U+0DDC) e0b79c à· SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA (U+0DDD) e0b79d à·ž SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA (U+0DDE) e0b79e à·Ÿ SINHALA VOWEL SIGN GAYANUKITTA (U+0DDF) e0b79f à·² SINHALA VOWEL SIGN DIGA GAETTA-PILLA (U+0DF2) e0b7b2 à·³ SINHALA VOWEL SIGN DIGA GAYANUKITTA (U+0DF3) e0b7b3 à·´ SINHALA PUNCTUATION KUNDDALIYA (U+0DF4) e0b7b4 ภTHAI CHARACTER KO KAI (U+0E01) e0b881 ข THAI CHARACTER KHO KHAI (U+0E02) e0b882 ฃ THAI CHARACTER KHO KHUAT (U+0E03) e0b883 ค THAI CHARACTER KHO KHWAI (U+0E04) e0b884 ฅ THAI CHARACTER KHO KHON (U+0E05) e0b885 ฆ THAI CHARACTER KHO RAKHANG (U+0E06) e0b886 ง THAI CHARACTER NGO NGU (U+0E07) e0b887 จ THAI CHARACTER CHO CHAN (U+0E08) e0b888 ฉ THAI CHARACTER CHO CHING (U+0E09) e0b889 ช THAI CHARACTER CHO CHANG (U+0E0A) e0b88a ซ THAI CHARACTER SO SO (U+0E0B) e0b88b ฌ THAI CHARACTER CHO CHOE (U+0E0C) e0b88c ภTHAI CHARACTER YO YING (U+0E0D) e0b88d ฎ THAI CHARACTER DO CHADA (U+0E0E) e0b88e ภTHAI CHARACTER TO PATAK (U+0E0F) e0b88f ภTHAI CHARACTER THO THAN (U+0E10) e0b890 ฑ THAI CHARACTER THO NANGMONTHO (U+0E11) e0b891 ฒ THAI CHARACTER THO PHUTHAO (U+0E12) e0b892 ณ THAI CHARACTER NO NEN (U+0E13) e0b893 ด THAI CHARACTER DO DEK (U+0E14) e0b894 ต THAI CHARACTER TO TAO (U+0E15) e0b895 ถ THAI CHARACTER THO THUNG (U+0E16) e0b896 ท THAI CHARACTER THO THAHAN (U+0E17) e0b897 ธ THAI CHARACTER THO THONG (U+0E18) e0b898 น THAI CHARACTER NO NU (U+0E19) e0b899 บ THAI CHARACTER BO BAIMAI (U+0E1A) e0b89a ป THAI CHARACTER PO PLA (U+0E1B) e0b89b ผ THAI CHARACTER PHO PHUNG (U+0E1C) e0b89c ภTHAI CHARACTER FO FA (U+0E1D) e0b89d พ THAI CHARACTER PHO PHAN (U+0E1E) e0b89e ฟ THAI CHARACTER FO FAN (U+0E1F) e0b89f ภ THAI CHARACTER PHO SAMPHAO (U+0E20) e0b8a0 ม THAI CHARACTER MO MA (U+0E21) e0b8a1 ย THAI CHARACTER YO YAK (U+0E22) e0b8a2 ร THAI CHARACTER RO RUA (U+0E23) e0b8a3 ฤ THAI CHARACTER RU (U+0E24) e0b8a4 ล THAI CHARACTER LO LING (U+0E25) e0b8a5 ฦ THAI CHARACTER LU (U+0E26) e0b8a6 ว THAI CHARACTER WO WAEN (U+0E27) e0b8a7 ศ THAI CHARACTER SO SALA (U+0E28) e0b8a8 ษ THAI CHARACTER SO RUSI (U+0E29) e0b8a9 ส THAI CHARACTER SO SUA (U+0E2A) e0b8aa ห THAI CHARACTER HO HIP (U+0E2B) e0b8ab ฬ THAI CHARACTER LO CHULA (U+0E2C) e0b8ac อ THAI CHARACTER O ANG (U+0E2D) e0b8ad ฮ THAI CHARACTER HO NOKHUK (U+0E2E) e0b8ae ฯ THAI CHARACTER PAIYANNOI (U+0E2F) e0b8af ะ THAI CHARACTER SARA A (U+0E30) e0b8b0 ั THAI CHARACTER MAI HAN-AKAT (U+0E31) e0b8b1 า THAI CHARACTER SARA AA (U+0E32) e0b8b2 ำ THAI CHARACTER SARA AM (U+0E33) e0b8b3 ิ THAI CHARACTER SARA I (U+0E34) e0b8b4 ี THAI CHARACTER SARA II (U+0E35) e0b8b5 ึ THAI CHARACTER SARA UE (U+0E36) e0b8b6 ื THAI CHARACTER SARA UEE (U+0E37) e0b8b7 ุ THAI CHARACTER SARA U (U+0E38) e0b8b8 ู THAI CHARACTER SARA UU (U+0E39) e0b8b9 ฺ THAI CHARACTER PHINTHU (U+0E3A) e0b8ba ฿ THAI CURRENCY SYMBOL BAHT (U+0E3F) e0b8bf เ THAI CHARACTER SARA E (U+0E40) e0b980 ๠THAI CHARACTER SARA AE (U+0E41) e0b981 โ THAI CHARACTER SARA O (U+0E42) e0b982 ใ THAI CHARACTER SARA AI MAIMUAN (U+0E43) e0b983 ไ THAI CHARACTER SARA AI MAIMALAI (U+0E44) e0b984 ๅ THAI CHARACTER LAKKHANGYAO (U+0E45) e0b985 ๆ THAI CHARACTER MAIYAMOK (U+0E46) e0b986 ็ THAI CHARACTER MAITAIKHU (U+0E47) e0b987 ่ THAI CHARACTER MAI EK (U+0E48) e0b988 ้ THAI CHARACTER MAI THO (U+0E49) e0b989 ๊ THAI CHARACTER MAI TRI (U+0E4A) e0b98a ๋ THAI CHARACTER MAI CHATTAWA (U+0E4B) e0b98b ์ THAI CHARACTER THANTHAKHAT (U+0E4C) e0b98c ๠THAI CHARACTER NIKHAHIT (U+0E4D) e0b98d ๎ THAI CHARACTER YAMAKKAN (U+0E4E) e0b98e ๠THAI CHARACTER FONGMAN (U+0E4F) e0b98f ๠THAI DIGIT ZERO (U+0E50) e0b990 ๑ THAI DIGIT ONE (U+0E51) e0b991 ๒ THAI DIGIT TWO (U+0E52) e0b992 ๓ THAI DIGIT THREE (U+0E53) e0b993 ๔ THAI DIGIT FOUR (U+0E54) e0b994 ๕ THAI DIGIT FIVE (U+0E55) e0b995 ๖ THAI DIGIT SIX (U+0E56) e0b996 ๗ THAI DIGIT SEVEN (U+0E57) e0b997 ๘ THAI DIGIT EIGHT (U+0E58) e0b998 ๙ THAI DIGIT NINE (U+0E59) e0b999 ๚ THAI CHARACTER ANGKHANKHU (U+0E5A) e0b99a ๛ THAI CHARACTER KHOMUT (U+0E5B) e0b99b ຠLAO LETTER KO (U+0E81) e0ba81 ຂ LAO LETTER KHO SUNG (U+0E82) e0ba82 ຄ LAO LETTER KHO TAM (U+0E84) e0ba84 ງ LAO LETTER NGO (U+0E87) e0ba87 ຈ LAO LETTER CO (U+0E88) e0ba88 ຊ LAO LETTER SO TAM (U+0E8A) e0ba8a ຠLAO LETTER NYO (U+0E8D) e0ba8d ດ LAO LETTER DO (U+0E94) e0ba94 ຕ LAO LETTER TO (U+0E95) e0ba95 ຖ LAO LETTER THO SUNG (U+0E96) e0ba96 ທ LAO LETTER THO TAM (U+0E97) e0ba97 ນ LAO LETTER NO (U+0E99) e0ba99 ບ LAO LETTER BO (U+0E9A) e0ba9a ປ LAO LETTER PO (U+0E9B) e0ba9b ຜ LAO LETTER PHO SUNG (U+0E9C) e0ba9c ຠLAO LETTER FO TAM (U+0E9D) e0ba9d ພ LAO LETTER PHO TAM (U+0E9E) e0ba9e ຟ LAO LETTER FO SUNG (U+0E9F) e0ba9f ມ LAO LETTER MO (U+0EA1) e0baa1 ຢ LAO LETTER YO (U+0EA2) e0baa2 ຣ LAO LETTER LO LING (U+0EA3) e0baa3 ລ LAO LETTER LO LOOT (U+0EA5) e0baa5 ວ LAO LETTER WO (U+0EA7) e0baa7 ສ LAO LETTER SO SUNG (U+0EAA) e0baaa ຫ LAO LETTER HO SUNG (U+0EAB) e0baab ອ LAO LETTER O (U+0EAD) e0baad More... Character Description Encoded Byte ຮ LAO LETTER HO TAM (U+0EAE) e0baae ຯ LAO ELLIPSIS (U+0EAF) e0baaf ະ LAO VOWEL SIGN A (U+0EB0) e0bab0 ັ LAO VOWEL SIGN MAI KAN (U+0EB1) e0bab1 າ LAO VOWEL SIGN AA (U+0EB2) e0bab2 ຳ LAO VOWEL SIGN AM (U+0EB3) e0bab3 ິ LAO VOWEL SIGN I (U+0EB4) e0bab4 ີ LAO VOWEL SIGN II (U+0EB5) e0bab5 ຶ LAO VOWEL SIGN Y (U+0EB6) e0bab6 ື LAO VOWEL SIGN YY (U+0EB7) e0bab7 ຸ LAO VOWEL SIGN U (U+0EB8) e0bab8 ູ LAO VOWEL SIGN UU (U+0EB9) e0bab9 ົ LAO VOWEL SIGN MAI KON (U+0EBB) e0babb ຼ LAO SEMIVOWEL SIGN LO (U+0EBC) e0babc ຽ LAO SEMIVOWEL SIGN NYO (U+0EBD) e0babd ເ LAO VOWEL SIGN E (U+0EC0) e0bb80 à» LAO VOWEL SIGN EI (U+0EC1) e0bb81 ໂ LAO VOWEL SIGN O (U+0EC2) e0bb82 ໃ LAO VOWEL SIGN AY (U+0EC3) e0bb83 ໄ LAO VOWEL SIGN AI (U+0EC4) e0bb84 ໆ LAO KO LA (U+0EC6) e0bb86 ່ LAO TONE MAI EK (U+0EC8) e0bb88 ້ LAO TONE MAI THO (U+0EC9) e0bb89 ໊ LAO TONE MAI TI (U+0ECA) e0bb8a ໋ LAO TONE MAI CATAWA (U+0ECB) e0bb8b ໌ LAO CANCELLATION MARK (U+0ECC) e0bb8c à» LAO NIGGAHITA (U+0ECD) e0bb8d à» LAO DIGIT ZERO (U+0ED0) e0bb90 ໑ LAO DIGIT ONE (U+0ED1) e0bb91 à»’ LAO DIGIT TWO (U+0ED2) e0bb92 ໓ LAO DIGIT THREE (U+0ED3) e0bb93 à»” LAO DIGIT FOUR (U+0ED4) e0bb94 ໕ LAO DIGIT FIVE (U+0ED5) e0bb95 à»– LAO DIGIT SIX (U+0ED6) e0bb96 à»— LAO DIGIT SEVEN (U+0ED7) e0bb97 ໘ LAO DIGIT EIGHT (U+0ED8) e0bb98 à»™ LAO DIGIT NINE (U+0ED9) e0bb99 ໜ LAO HO NO (U+0EDC) e0bb9c à» LAO HO MO (U+0EDD) e0bb9d ༀ TIBETAN SYLLABLE OM (U+0F00) e0bc80 ༠TIBETAN MARK GTER YIG MGO TRUNCATED A (U+0F01) e0bc81 ༂ TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA (U+0F02) e0bc82 ༃ TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA (U+0F03) e0bc83 ༄ TIBETAN MARK INITIAL YIG MGO MDUN MA (U+0F04) e0bc84 ༅ TIBETAN MARK CLOSING YIG MGO SGAB MA (U+0F05) e0bc85 ༆ TIBETAN MARK CARET YIG MGO PHUR SHAD MA (U+0F06) e0bc86 ༇ TIBETAN MARK YIG MGO TSHEG SHAD MA (U+0F07) e0bc87 ༈ TIBETAN MARK SBRUL SHAD (U+0F08) e0bc88 ༉ TIBETAN MARK BSKUR YIG MGO (U+0F09) e0bc89 ༊ TIBETAN MARK BKA- SHOG YIG MGO (U+0F0A) e0bc8a ་ TIBETAN MARK INTERSYLLABIC TSHEG (U+0F0B) e0bc8b ༌ TIBETAN MARK DELIMITER TSHEG BSTAR (U+0F0C) e0bc8c ༠TIBETAN MARK SHAD (U+0F0D) e0bc8d ༎ TIBETAN MARK NYIS SHAD (U+0F0E) e0bc8e ༠TIBETAN MARK TSHEG SHAD (U+0F0F) e0bc8f ༠TIBETAN MARK NYIS TSHEG SHAD (U+0F10) e0bc90 ༑ TIBETAN MARK RIN CHEN SPUNGS SHAD (U+0F11) e0bc91 ༒ TIBETAN MARK RGYA GRAM SHAD (U+0F12) e0bc92 ༓ TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN (U+0F13) e0bc93 ༔ TIBETAN MARK GTER TSHEG (U+0F14) e0bc94 ༕ TIBETAN LOGOTYPE SIGN CHAD RTAGS (U+0F15) e0bc95 ༖ TIBETAN LOGOTYPE SIGN LHAG RTAGS (U+0F16) e0bc96 ༗ TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS (U+0F17) e0bc97 ༘ TIBETAN ASTROLOGICAL SIGN -KHYUD PA (U+0F18) e0bc98 ༙ TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS (U+0F19) e0bc99 ༚ TIBETAN SIGN RDEL DKAR GCIG (U+0F1A) e0bc9a ༛ TIBETAN SIGN RDEL DKAR GNYIS (U+0F1B) e0bc9b ༜ TIBETAN SIGN RDEL DKAR GSUM (U+0F1C) e0bc9c ༠TIBETAN SIGN RDEL NAG GCIG (U+0F1D) e0bc9d ༞ TIBETAN SIGN RDEL NAG GNYIS (U+0F1E) e0bc9e ༟ TIBETAN SIGN RDEL DKAR RDEL NAG (U+0F1F) e0bc9f ༠ TIBETAN DIGIT ZERO (U+0F20) e0bca0 ༡ TIBETAN DIGIT ONE (U+0F21) e0bca1 ༢ TIBETAN DIGIT TWO (U+0F22) e0bca2 ༣ TIBETAN DIGIT THREE (U+0F23) e0bca3 ༤ TIBETAN DIGIT FOUR (U+0F24) e0bca4 ༥ TIBETAN DIGIT FIVE (U+0F25) e0bca5 ༦ TIBETAN DIGIT SIX (U+0F26) e0bca6 ༧ TIBETAN DIGIT SEVEN (U+0F27) e0bca7 ༨ TIBETAN DIGIT EIGHT (U+0F28) e0bca8 ༩ TIBETAN DIGIT NINE (U+0F29) e0bca9 ༪ TIBETAN DIGIT HALF ONE (U+0F2A) e0bcaa ༫ TIBETAN DIGIT HALF TWO (U+0F2B) e0bcab ༬ TIBETAN DIGIT HALF THREE (U+0F2C) e0bcac ༭ TIBETAN DIGIT HALF FOUR (U+0F2D) e0bcad ༮ TIBETAN DIGIT HALF FIVE (U+0F2E) e0bcae ༯ TIBETAN DIGIT HALF SIX (U+0F2F) e0bcaf ༰ TIBETAN DIGIT HALF SEVEN (U+0F30) e0bcb0 ༱ TIBETAN DIGIT HALF EIGHT (U+0F31) e0bcb1 ༲ TIBETAN DIGIT HALF NINE (U+0F32) e0bcb2 ༳ TIBETAN DIGIT HALF ZERO (U+0F33) e0bcb3 ༴ TIBETAN MARK BSDUS RTAGS (U+0F34) e0bcb4 ༵ TIBETAN MARK NGAS BZUNG NYI ZLA (U+0F35) e0bcb5 ༶ TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN (U+0F36) e0bcb6 ༷ TIBETAN MARK NGAS BZUNG SGOR RTAGS (U+0F37) e0bcb7 ༸ TIBETAN MARK CHE MGO (U+0F38) e0bcb8 ༹ TIBETAN MARK TSA -PHRU (U+0F39) e0bcb9 ༺ TIBETAN MARK GUG RTAGS GYON (U+0F3A) e0bcba ༻ TIBETAN MARK GUG RTAGS GYAS (U+0F3B) e0bcbb ༼ TIBETAN MARK ANG KHANG GYON (U+0F3C) e0bcbc ༽ TIBETAN MARK ANG KHANG GYAS (U+0F3D) e0bcbd ༾ TIBETAN SIGN YAR TSHES (U+0F3E) e0bcbe ༿ TIBETAN SIGN MAR TSHES (U+0F3F) e0bcbf ཀ TIBETAN LETTER KA (U+0F40) e0bd80 འTIBETAN LETTER KHA (U+0F41) e0bd81 ག TIBETAN LETTER GA (U+0F42) e0bd82 གྷ TIBETAN LETTER GHA (U+0F43) e0bd83 ང TIBETAN LETTER NGA (U+0F44) e0bd84 ཅ TIBETAN LETTER CA (U+0F45) e0bd85 ཆ TIBETAN LETTER CHA (U+0F46) e0bd86 ཇ TIBETAN LETTER JA (U+0F47) e0bd87 ཉ TIBETAN LETTER NYA (U+0F49) e0bd89 ཊ TIBETAN LETTER TTA (U+0F4A) e0bd8a ཋ TIBETAN LETTER TTHA (U+0F4B) e0bd8b ཌ TIBETAN LETTER DDA (U+0F4C) e0bd8c འTIBETAN LETTER DDHA (U+0F4D) e0bd8d ཎ TIBETAN LETTER NNA (U+0F4E) e0bd8e འTIBETAN LETTER TA (U+0F4F) e0bd8f འTIBETAN LETTER THA (U+0F50) e0bd90 ད TIBETAN LETTER DA (U+0F51) e0bd91 དྷ TIBETAN LETTER DHA (U+0F52) e0bd92 ན TIBETAN LETTER NA (U+0F53) e0bd93 པ TIBETAN LETTER PA (U+0F54) e0bd94 ཕ TIBETAN LETTER PHA (U+0F55) e0bd95 བ TIBETAN LETTER BA (U+0F56) e0bd96 བྷ TIBETAN LETTER BHA (U+0F57) e0bd97 མ TIBETAN LETTER MA (U+0F58) e0bd98 ཙ TIBETAN LETTER TSA (U+0F59) e0bd99 ཚ TIBETAN LETTER TSHA (U+0F5A) e0bd9a ཛ TIBETAN LETTER DZA (U+0F5B) e0bd9b ཛྷ TIBETAN LETTER DZHA (U+0F5C) e0bd9c འTIBETAN LETTER WA (U+0F5D) e0bd9d ཞ TIBETAN LETTER ZHA (U+0F5E) e0bd9e ཟ TIBETAN LETTER ZA (U+0F5F) e0bd9f འ TIBETAN LETTER -A (U+0F60) e0bda0 ཡ TIBETAN LETTER YA (U+0F61) e0bda1 ར TIBETAN LETTER RA (U+0F62) e0bda2 ལ TIBETAN LETTER LA (U+0F63) e0bda3 ཤ TIBETAN LETTER SHA (U+0F64) e0bda4 ཥ TIBETAN LETTER SSA (U+0F65) e0bda5 ས TIBETAN LETTER SA (U+0F66) e0bda6 ཧ TIBETAN LETTER HA (U+0F67) e0bda7 ཨ TIBETAN LETTER A (U+0F68) e0bda8 ཀྵ TIBETAN LETTER KSSA (U+0F69) e0bda9 ཪ TIBETAN LETTER FIXED-FORM RA (U+0F6A) e0bdaa ཫ TIBETAN LETTER KKA (U+0F6B) e0bdab ཬ TIBETAN LETTER RRA (U+0F6C) e0bdac ཱ TIBETAN VOWEL SIGN AA (U+0F71) e0bdb1 ི TIBETAN VOWEL SIGN I (U+0F72) e0bdb2 ཱི TIBETAN VOWEL SIGN II (U+0F73) e0bdb3 ུ TIBETAN VOWEL SIGN U (U+0F74) e0bdb4 ཱུ TIBETAN VOWEL SIGN UU (U+0F75) e0bdb5 ྲྀ TIBETAN VOWEL SIGN VOCALIC R (U+0F76) e0bdb6 ཷ TIBETAN VOWEL SIGN VOCALIC RR (U+0F77) e0bdb7 ླྀ TIBETAN VOWEL SIGN VOCALIC L (U+0F78) e0bdb8 ཹ TIBETAN VOWEL SIGN VOCALIC LL (U+0F79) e0bdb9 ེ TIBETAN VOWEL SIGN E (U+0F7A) e0bdba ཻ TIBETAN VOWEL SIGN EE (U+0F7B) e0bdbb ོ TIBETAN VOWEL SIGN O (U+0F7C) e0bdbc ཽ TIBETAN VOWEL SIGN OO (U+0F7D) e0bdbd ཾ TIBETAN SIGN RJES SU NGA RO (U+0F7E) e0bdbe ཿ TIBETAN SIGN RNAM BCAD (U+0F7F) e0bdbf ྀ TIBETAN VOWEL SIGN REVERSED I (U+0F80) e0be80 ྠTIBETAN VOWEL SIGN REVERSED II (U+0F81) e0be81 ྂ TIBETAN SIGN NYI ZLA NAA DA (U+0F82) e0be82 ྃ TIBETAN SIGN SNA LDAN (U+0F83) e0be83 ྄ TIBETAN MARK HALANTA (U+0F84) e0be84 ྅ TIBETAN MARK PALUTA (U+0F85) e0be85 ྆ TIBETAN SIGN LCI RTAGS (U+0F86) e0be86 ྇ TIBETAN SIGN YANG RTAGS (U+0F87) e0be87 ྈ TIBETAN SIGN LCE TSA CAN (U+0F88) e0be88 ྉ TIBETAN SIGN MCHU CAN (U+0F89) e0be89 ྊ TIBETAN SIGN GRU CAN RGYINGS (U+0F8A) e0be8a ྋ TIBETAN SIGN GRU MED RGYINGS (U+0F8B) e0be8b ྌ TIBETAN SIGN INVERTED MCHU CAN (U+0F8C) e0be8c ྠTIBETAN SUBJOINED SIGN LCE TSA CAN (U+0F8D) e0be8d ྎ TIBETAN SUBJOINED SIGN MCHU CAN (U+0F8E) e0be8e ྠTIBETAN SUBJOINED SIGN INVERTED MCHU CAN (U+0F8F) e0be8f ྠTIBETAN SUBJOINED LETTER KA (U+0F90) e0be90 ྑ TIBETAN SUBJOINED LETTER KHA (U+0F91) e0be91 ྒ TIBETAN SUBJOINED LETTER GA (U+0F92) e0be92 ྒྷ TIBETAN SUBJOINED LETTER GHA (U+0F93) e0be93 ྔ TIBETAN SUBJOINED LETTER NGA (U+0F94) e0be94 ྕ TIBETAN SUBJOINED LETTER CA (U+0F95) e0be95 ྖ TIBETAN SUBJOINED LETTER CHA (U+0F96) e0be96 ྗ TIBETAN SUBJOINED LETTER JA (U+0F97) e0be97 ྙ TIBETAN SUBJOINED LETTER NYA (U+0F99) e0be99 ྚ TIBETAN SUBJOINED LETTER TTA (U+0F9A) e0be9a ྛ TIBETAN SUBJOINED LETTER TTHA (U+0F9B) e0be9b ྜ TIBETAN SUBJOINED LETTER DDA (U+0F9C) e0be9c ྠTIBETAN SUBJOINED LETTER DDHA (U+0F9D) e0be9d ྞ TIBETAN SUBJOINED LETTER NNA (U+0F9E) e0be9e ྟ TIBETAN SUBJOINED LETTER TA (U+0F9F) e0be9f ྠ TIBETAN SUBJOINED LETTER THA (U+0FA0) e0bea0 ྡ TIBETAN SUBJOINED LETTER DA (U+0FA1) e0bea1 ྡྷ TIBETAN SUBJOINED LETTER DHA (U+0FA2) e0bea2 ྣ TIBETAN SUBJOINED LETTER NA (U+0FA3) e0bea3 ྤ TIBETAN SUBJOINED LETTER PA (U+0FA4) e0bea4 ྥ TIBETAN SUBJOINED LETTER PHA (U+0FA5) e0bea5 ྦ TIBETAN SUBJOINED LETTER BA (U+0FA6) e0bea6 ྦྷ TIBETAN SUBJOINED LETTER BHA (U+0FA7) e0bea7 ྨ TIBETAN SUBJOINED LETTER MA (U+0FA8) e0bea8 ྩ TIBETAN SUBJOINED LETTER TSA (U+0FA9) e0bea9 ྪ TIBETAN SUBJOINED LETTER TSHA (U+0FAA) e0beaa ྫ TIBETAN SUBJOINED LETTER DZA (U+0FAB) e0beab ྫྷ TIBETAN SUBJOINED LETTER DZHA (U+0FAC) e0beac ྭ TIBETAN SUBJOINED LETTER WA (U+0FAD) e0bead ྮ TIBETAN SUBJOINED LETTER ZHA (U+0FAE) e0beae ྯ TIBETAN SUBJOINED LETTER ZA (U+0FAF) e0beaf ྰ TIBETAN SUBJOINED LETTER -A (U+0FB0) e0beb0 ྱ TIBETAN SUBJOINED LETTER YA (U+0FB1) e0beb1 ྲ TIBETAN SUBJOINED LETTER RA (U+0FB2) e0beb2 ླ TIBETAN SUBJOINED LETTER LA (U+0FB3) e0beb3 ྴ TIBETAN SUBJOINED LETTER SHA (U+0FB4) e0beb4 ྵ TIBETAN SUBJOINED LETTER SSA (U+0FB5) e0beb5 ྶ TIBETAN SUBJOINED LETTER SA (U+0FB6) e0beb6 ྷ TIBETAN SUBJOINED LETTER HA (U+0FB7) e0beb7 ྸ TIBETAN SUBJOINED LETTER A (U+0FB8) e0beb8 ྐྵ TIBETAN SUBJOINED LETTER KSSA (U+0FB9) e0beb9 ྺ TIBETAN SUBJOINED LETTER FIXED-FORM WA (U+0FBA) e0beba ྻ TIBETAN SUBJOINED LETTER FIXED-FORM YA (U+0FBB) e0bebb ྼ TIBETAN SUBJOINED LETTER FIXED-FORM RA (U+0FBC) e0bebc ྾ TIBETAN KU RU KHA (U+0FBE) e0bebe ྿ TIBETAN KU RU KHA BZHI MIG CAN (U+0FBF) e0bebf à¿€ TIBETAN CANTILLATION SIGN HEAVY BEAT (U+0FC0) e0bf80 à¿ TIBETAN CANTILLATION SIGN LIGHT BEAT (U+0FC1) e0bf81 à¿‚ TIBETAN CANTILLATION SIGN CANG TE-U (U+0FC2) e0bf82 ࿃ TIBETAN CANTILLATION SIGN SBUB -CHAL (U+0FC3) e0bf83 à¿„ TIBETAN SYMBOL DRIL BU (U+0FC4) e0bf84 à¿… TIBETAN SYMBOL RDO RJE (U+0FC5) e0bf85 ࿆ TIBETAN SYMBOL PADMA GDAN (U+0FC6) e0bf86 ࿇ TIBETAN SYMBOL RDO RJE RGYA GRAM (U+0FC7) e0bf87 ࿈ TIBETAN SYMBOL PHUR PA (U+0FC8) e0bf88 ࿉ TIBETAN SYMBOL NOR BU (U+0FC9) e0bf89 ࿊ TIBETAN SYMBOL NOR BU NYIS -KHYIL (U+0FCA) e0bf8a à¿‹ TIBETAN SYMBOL NOR BU GSUM -KHYIL (U+0FCB) e0bf8b ࿌ TIBETAN SYMBOL NOR BU BZHI -KHYIL (U+0FCC) e0bf8c ࿎ TIBETAN SIGN RDEL NAG RDEL DKAR (U+0FCE) e0bf8e à¿ TIBETAN SIGN RDEL NAG GSUM (U+0FCF) e0bf8f à¿ TIBETAN MARK BSKA- SHOG GI MGO RGYAN (U+0FD0) e0bf90 à¿‘ TIBETAN MARK MNYAM YIG GI MGO RGYAN (U+0FD1) e0bf91 à¿’ TIBETAN MARK NYIS TSHEG (U+0FD2) e0bf92 à¿“ TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA (U+0FD3) e0bf93 à¿” TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA (U+0FD4) e0bf94 à¿• RIGHT-FACING SVASTI SIGN (U+0FD5) e0bf95 à¿– LEFT-FACING SVASTI SIGN (U+0FD6) e0bf96 à¿— RIGHT-FACING SVASTI SIGN WITH DOTS (U+0FD7) e0bf97 ࿘ LEFT-FACING SVASTI SIGN WITH DOTS (U+0FD8) e0bf98 à¿™ TIBETAN MARK LEADING MCHAN RTAGS (U+0FD9) e0bf99 ࿚ TIBETAN MARK TRAILING MCHAN RTAGS (U+0FDA) e0bf9a က MYANMAR LETTER KA (U+1000) e18080 ဠMYANMAR LETTER KHA (U+1001) e18081 ဂ MYANMAR LETTER GA (U+1002) e18082 ဃ MYANMAR LETTER GHA (U+1003) e18083 င MYANMAR LETTER NGA (U+1004) e18084 စ MYANMAR LETTER CA (U+1005) e18085 ဆ MYANMAR LETTER CHA (U+1006) e18086 ဇ MYANMAR LETTER JA (U+1007) e18087 ဈ MYANMAR LETTER JHA (U+1008) e18088 ဉ MYANMAR LETTER NYA (U+1009) e18089 ည MYANMAR LETTER NNYA (U+100A) e1808a ဋ MYANMAR LETTER TTA (U+100B) e1808b ဌ MYANMAR LETTER TTHA (U+100C) e1808c ဠMYANMAR LETTER DDA (U+100D) e1808d ဎ MYANMAR LETTER DDHA (U+100E) e1808e ဠMYANMAR LETTER NNA (U+100F) e1808f ဠMYANMAR LETTER TA (U+1010) e18090 ထ MYANMAR LETTER THA (U+1011) e18091 ဒ MYANMAR LETTER DA (U+1012) e18092 ဓ MYANMAR LETTER DHA (U+1013) e18093 န MYANMAR LETTER NA (U+1014) e18094 ပ MYANMAR LETTER PA (U+1015) e18095 ဖ MYANMAR LETTER PHA (U+1016) e18096 ဗ MYANMAR LETTER BA (U+1017) e18097 ဘ MYANMAR LETTER BHA (U+1018) e18098 မ MYANMAR LETTER MA (U+1019) e18099 ယ MYANMAR LETTER YA (U+101A) e1809a ရ MYANMAR LETTER RA (U+101B) e1809b လ MYANMAR LETTER LA (U+101C) e1809c ဠMYANMAR LETTER WA (U+101D) e1809d သ MYANMAR LETTER SA (U+101E) e1809e ဟ MYANMAR LETTER HA (U+101F) e1809f ဠ MYANMAR LETTER LLA (U+1020) e180a0 အ MYANMAR LETTER A (U+1021) e180a1 ဢ MYANMAR LETTER SHAN A (U+1022) e180a2 ဣ MYANMAR LETTER I (U+1023) e180a3 ဤ MYANMAR LETTER II (U+1024) e180a4 ဥ MYANMAR LETTER U (U+1025) e180a5 ဦ MYANMAR LETTER UU (U+1026) e180a6 ဧ MYANMAR LETTER E (U+1027) e180a7 ဨ MYANMAR LETTER MON E (U+1028) e180a8 ဩ MYANMAR LETTER O (U+1029) e180a9 ဪ MYANMAR LETTER AU (U+102A) e180aa ါ MYANMAR VOWEL SIGN TALL AA (U+102B) e180ab ာ MYANMAR VOWEL SIGN AA (U+102C) e180ac ိ MYANMAR VOWEL SIGN I (U+102D) e180ad ီ MYANMAR VOWEL SIGN II (U+102E) e180ae ု MYANMAR VOWEL SIGN U (U+102F) e180af ူ MYANMAR VOWEL SIGN UU (U+1030) e180b0 ေ MYANMAR VOWEL SIGN E (U+1031) e180b1 ဲ MYANMAR VOWEL SIGN AI (U+1032) e180b2 ဳ MYANMAR VOWEL SIGN MON II (U+1033) e180b3 ဴ MYANMAR VOWEL SIGN MON O (U+1034) e180b4 ဵ MYANMAR VOWEL SIGN E ABOVE (U+1035) e180b5 ံ MYANMAR SIGN ANUSVARA (U+1036) e180b6 ့ MYANMAR SIGN DOT BELOW (U+1037) e180b7 း MYANMAR SIGN VISARGA (U+1038) e180b8 ္ MYANMAR SIGN VIRAMA (U+1039) e180b9 ် MYANMAR SIGN ASAT (U+103A) e180ba ျ MYANMAR CONSONANT SIGN MEDIAL YA (U+103B) e180bb ြ MYANMAR CONSONANT SIGN MEDIAL RA (U+103C) e180bc ွ MYANMAR CONSONANT SIGN MEDIAL WA (U+103D) e180bd ှ MYANMAR CONSONANT SIGN MEDIAL HA (U+103E) e180be ဿ MYANMAR LETTER GREAT SA (U+103F) e180bf ဠMYANMAR DIGIT ZERO (U+1040) e18180 á MYANMAR DIGIT ONE (U+1041) e18181 á‚ MYANMAR DIGIT TWO (U+1042) e18182 რMYANMAR DIGIT THREE (U+1043) e18183 á„ MYANMAR DIGIT FOUR (U+1044) e18184 á… MYANMAR DIGIT FIVE (U+1045) e18185 ᆠMYANMAR DIGIT SIX (U+1046) e18186 ᇠMYANMAR DIGIT SEVEN (U+1047) e18187 ሠMYANMAR DIGIT EIGHT (U+1048) e18188 በMYANMAR DIGIT NINE (U+1049) e18189 አMYANMAR SIGN LITTLE SECTION (U+104A) e1818a á‹ MYANMAR SIGN SECTION (U+104B) e1818b ጠMYANMAR SYMBOL LOCATIVE (U+104C) e1818c á MYANMAR SYMBOL COMPLETED (U+104D) e1818d ᎠMYANMAR SYMBOL AFOREMENTIONED (U+104E) e1818e á MYANMAR SYMBOL GENITIVE (U+104F) e1818f á MYANMAR LETTER SHA (U+1050) e18190 á‘ MYANMAR LETTER SSA (U+1051) e18191 á’ MYANMAR LETTER VOCALIC R (U+1052) e18192 á“ MYANMAR LETTER VOCALIC RR (U+1053) e18193 á” MYANMAR LETTER VOCALIC L (U+1054) e18194 á• MYANMAR LETTER VOCALIC LL (U+1055) e18195 á– MYANMAR VOWEL SIGN VOCALIC R (U+1056) e18196 á— MYANMAR VOWEL SIGN VOCALIC RR (U+1057) e18197 ᘠMYANMAR VOWEL SIGN VOCALIC L (U+1058) e18198 á™ MYANMAR VOWEL SIGN VOCALIC LL (U+1059) e18199 áš MYANMAR LETTER MON NGA (U+105A) e1819a á› MYANMAR LETTER MON JHA (U+105B) e1819b ᜠMYANMAR LETTER MON BBA (U+105C) e1819c á MYANMAR LETTER MON BBE (U+105D) e1819d áž MYANMAR CONSONANT SIGN MON MEDIAL NA (U+105E) e1819e ០MYANMAR CONSONANT SIGN MON MEDIAL MA (U+105F) e1819f á  MYANMAR CONSONANT SIGN MON MEDIAL LA (U+1060) e181a0 á¡ MYANMAR LETTER SGAW KAREN SHA (U+1061) e181a1 ᢠMYANMAR VOWEL SIGN SGAW KAREN EU (U+1062) e181a2 ᣠMYANMAR TONE MARK SGAW KAREN HATHI (U+1063) e181a3 ᤠMYANMAR TONE MARK SGAW KAREN KE PHO (U+1064) e181a4 ᥠMYANMAR LETTER WESTERN PWO KAREN THA (U+1065) e181a5 ᦠMYANMAR LETTER WESTERN PWO KAREN PWA (U+1066) e181a6 á§ MYANMAR VOWEL SIGN WESTERN PWO KAREN EU (U+1067) e181a7 ᨠMYANMAR VOWEL SIGN WESTERN PWO KAREN UE (U+1068) e181a8 á© MYANMAR SIGN WESTERN PWO KAREN TONE-1 (U+1069) e181a9 ᪠MYANMAR SIGN WESTERN PWO KAREN TONE-2 (U+106A) e181aa á« MYANMAR SIGN WESTERN PWO KAREN TONE-3 (U+106B) e181ab ᬠMYANMAR SIGN WESTERN PWO KAREN TONE-4 (U+106C) e181ac á­ MYANMAR SIGN WESTERN PWO KAREN TONE-5 (U+106D) e181ad á® MYANMAR LETTER EASTERN PWO KAREN NNA (U+106E) e181ae ᯠMYANMAR LETTER EASTERN PWO KAREN YWA (U+106F) e181af á° MYANMAR LETTER EASTERN PWO KAREN GHWA (U+1070) e181b0 á± MYANMAR VOWEL SIGN GEBA KAREN I (U+1071) e181b1 á² MYANMAR VOWEL SIGN KAYAH OE (U+1072) e181b2 á³ MYANMAR VOWEL SIGN KAYAH U (U+1073) e181b3 á´ MYANMAR VOWEL SIGN KAYAH EE (U+1074) e181b4 áµ MYANMAR LETTER SHAN KA (U+1075) e181b5 á¶ MYANMAR LETTER SHAN KHA (U+1076) e181b6 á· MYANMAR LETTER SHAN GA (U+1077) e181b7 ḠMYANMAR LETTER SHAN CA (U+1078) e181b8 á¹ MYANMAR LETTER SHAN ZA (U+1079) e181b9 ẠMYANMAR LETTER SHAN NYA (U+107A) e181ba á» MYANMAR LETTER SHAN DA (U+107B) e181bb á¼ MYANMAR LETTER SHAN NA (U+107C) e181bc á½ MYANMAR LETTER SHAN PHA (U+107D) e181bd á¾ MYANMAR LETTER SHAN FA (U+107E) e181be á¿ MYANMAR LETTER SHAN BA (U+107F) e181bf á‚€ MYANMAR LETTER SHAN THA (U+1080) e18280 á‚ MYANMAR LETTER SHAN HA (U+1081) e18281 á‚‚ MYANMAR CONSONANT SIGN SHAN MEDIAL WA (U+1082) e18282 ႃ MYANMAR VOWEL SIGN SHAN AA (U+1083) e18283 á‚„ MYANMAR VOWEL SIGN SHAN E (U+1084) e18284 á‚… MYANMAR VOWEL SIGN SHAN E ABOVE (U+1085) e18285 ႆ MYANMAR VOWEL SIGN SHAN FINAL Y (U+1086) e18286 ႇ MYANMAR SIGN SHAN TONE-2 (U+1087) e18287 ႈ MYANMAR SIGN SHAN TONE-3 (U+1088) e18288 ႉ MYANMAR SIGN SHAN TONE-5 (U+1089) e18289 ႊ MYANMAR SIGN SHAN TONE-6 (U+108A) e1828a á‚‹ MYANMAR SIGN SHAN COUNCIL TONE-2 (U+108B) e1828b ႌ MYANMAR SIGN SHAN COUNCIL TONE-3 (U+108C) e1828c á‚ MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE (U+108D) e1828d ႎ MYANMAR LETTER RUMAI PALAUNG FA (U+108E) e1828e á‚ MYANMAR SIGN RUMAI PALAUNG TONE-5 (U+108F) e1828f á‚ MYANMAR SHAN DIGIT ZERO (U+1090) e18290 á‚‘ MYANMAR SHAN DIGIT ONE (U+1091) e18291 á‚’ MYANMAR SHAN DIGIT TWO (U+1092) e18292 á‚“ MYANMAR SHAN DIGIT THREE (U+1093) e18293 á‚” MYANMAR SHAN DIGIT FOUR (U+1094) e18294 á‚• MYANMAR SHAN DIGIT FIVE (U+1095) e18295 á‚– MYANMAR SHAN DIGIT SIX (U+1096) e18296 á‚— MYANMAR SHAN DIGIT SEVEN (U+1097) e18297 ႘ MYANMAR SHAN DIGIT EIGHT (U+1098) e18298 á‚™ MYANMAR SHAN DIGIT NINE (U+1099) e18299 ႚ MYANMAR SIGN KHAMTI TONE-1 (U+109A) e1829a á‚› MYANMAR SIGN KHAMTI TONE-3 (U+109B) e1829b ႜ MYANMAR VOWEL SIGN AITON A (U+109C) e1829c á‚ MYANMAR VOWEL SIGN AITON AI (U+109D) e1829d ႞ MYANMAR SYMBOL SHAN ONE (U+109E) e1829e ႟ MYANMAR SYMBOL SHAN EXCLAMATION (U+109F) e1829f á‚  GEORGIAN CAPITAL LETTER AN (U+10A0) e182a0 á‚¡ GEORGIAN CAPITAL LETTER BAN (U+10A1) e182a1 á‚¢ GEORGIAN CAPITAL LETTER GAN (U+10A2) e182a2 á‚£ GEORGIAN CAPITAL LETTER DON (U+10A3) e182a3 Ⴄ GEORGIAN CAPITAL LETTER EN (U+10A4) e182a4 á‚¥ GEORGIAN CAPITAL LETTER VIN (U+10A5) e182a5 Ⴆ GEORGIAN CAPITAL LETTER ZEN (U+10A6) e182a6 á‚§ GEORGIAN CAPITAL LETTER TAN (U+10A7) e182a7 Ⴈ GEORGIAN CAPITAL LETTER IN (U+10A8) e182a8 á‚© GEORGIAN CAPITAL LETTER KAN (U+10A9) e182a9 Ⴊ GEORGIAN CAPITAL LETTER LAS (U+10AA) e182aa á‚« GEORGIAN CAPITAL LETTER MAN (U+10AB) e182ab Ⴌ GEORGIAN CAPITAL LETTER NAR (U+10AC) e182ac á‚­ GEORGIAN CAPITAL LETTER ON (U+10AD) e182ad á‚® GEORGIAN CAPITAL LETTER PAR (U+10AE) e182ae Ⴏ GEORGIAN CAPITAL LETTER ZHAR (U+10AF) e182af á‚° GEORGIAN CAPITAL LETTER RAE (U+10B0) e182b0 Ⴑ GEORGIAN CAPITAL LETTER SAN (U+10B1) e182b1 Ⴒ GEORGIAN CAPITAL LETTER TAR (U+10B2) e182b2 Ⴓ GEORGIAN CAPITAL LETTER UN (U+10B3) e182b3 á‚´ GEORGIAN CAPITAL LETTER PHAR (U+10B4) e182b4 Ⴕ GEORGIAN CAPITAL LETTER KHAR (U+10B5) e182b5 á‚¶ GEORGIAN CAPITAL LETTER GHAN (U+10B6) e182b6 á‚· GEORGIAN CAPITAL LETTER QAR (U+10B7) e182b7 Ⴘ GEORGIAN CAPITAL LETTER SHIN (U+10B8) e182b8 Ⴙ GEORGIAN CAPITAL LETTER CHIN (U+10B9) e182b9 Ⴚ GEORGIAN CAPITAL LETTER CAN (U+10BA) e182ba á‚» GEORGIAN CAPITAL LETTER JIL (U+10BB) e182bb Ⴜ GEORGIAN CAPITAL LETTER CIL (U+10BC) e182bc Ⴝ GEORGIAN CAPITAL LETTER CHAR (U+10BD) e182bd Ⴞ GEORGIAN CAPITAL LETTER XAN (U+10BE) e182be á‚¿ GEORGIAN CAPITAL LETTER JHAN (U+10BF) e182bf Ⴠ GEORGIAN CAPITAL LETTER HAE (U+10C0) e18380 რGEORGIAN CAPITAL LETTER HE (U+10C1) e18381 Ⴢ GEORGIAN CAPITAL LETTER HIE (U+10C2) e18382 Ⴣ GEORGIAN CAPITAL LETTER WE (U+10C3) e18383 Ⴤ GEORGIAN CAPITAL LETTER HAR (U+10C4) e18384 Ⴥ GEORGIAN CAPITAL LETTER HOE (U+10C5) e18385 რGEORGIAN LETTER AN (U+10D0) e18390 ბ GEORGIAN LETTER BAN (U+10D1) e18391 გ GEORGIAN LETTER GAN (U+10D2) e18392 დ GEORGIAN LETTER DON (U+10D3) e18393 ე GEORGIAN LETTER EN (U+10D4) e18394 ვ GEORGIAN LETTER VIN (U+10D5) e18395 ზ GEORGIAN LETTER ZEN (U+10D6) e18396 თ GEORGIAN LETTER TAN (U+10D7) e18397 ი GEORGIAN LETTER IN (U+10D8) e18398 კ GEORGIAN LETTER KAN (U+10D9) e18399 ლ GEORGIAN LETTER LAS (U+10DA) e1839a მ GEORGIAN LETTER MAN (U+10DB) e1839b ნ GEORGIAN LETTER NAR (U+10DC) e1839c რGEORGIAN LETTER ON (U+10DD) e1839d პ GEORGIAN LETTER PAR (U+10DE) e1839e ჟ GEORGIAN LETTER ZHAR (U+10DF) e1839f რ GEORGIAN LETTER RAE (U+10E0) e183a0 ს GEORGIAN LETTER SAN (U+10E1) e183a1 ტ GEORGIAN LETTER TAR (U+10E2) e183a2 უ GEORGIAN LETTER UN (U+10E3) e183a3 ფ GEORGIAN LETTER PHAR (U+10E4) e183a4 ქ GEORGIAN LETTER KHAR (U+10E5) e183a5 ღ GEORGIAN LETTER GHAN (U+10E6) e183a6 ყ GEORGIAN LETTER QAR (U+10E7) e183a7 შ GEORGIAN LETTER SHIN (U+10E8) e183a8 ჩ GEORGIAN LETTER CHIN (U+10E9) e183a9 ც GEORGIAN LETTER CAN (U+10EA) e183aa ძ GEORGIAN LETTER JIL (U+10EB) e183ab წ GEORGIAN LETTER CIL (U+10EC) e183ac ჭ GEORGIAN LETTER CHAR (U+10ED) e183ad ხ GEORGIAN LETTER XAN (U+10EE) e183ae ჯ GEORGIAN LETTER JHAN (U+10EF) e183af ჰ GEORGIAN LETTER HAE (U+10F0) e183b0 ჱ GEORGIAN LETTER HE (U+10F1) e183b1 ჲ GEORGIAN LETTER HIE (U+10F2) e183b2 ჳ GEORGIAN LETTER WE (U+10F3) e183b3 ჴ GEORGIAN LETTER HAR (U+10F4) e183b4 ჵ GEORGIAN LETTER HOE (U+10F5) e183b5 ჶ GEORGIAN LETTER FI (U+10F6) e183b6 ჷ GEORGIAN LETTER YN (U+10F7) e183b7 ჸ GEORGIAN LETTER ELIFI (U+10F8) e183b8 ჹ GEORGIAN LETTER TURNED GAN (U+10F9) e183b9 ჺ GEORGIAN LETTER AIN (U+10FA) e183ba ჻ GEORGIAN PARAGRAPH SEPARATOR (U+10FB) e183bb ჼ MODIFIER LETTER GEORGIAN NAR (U+10FC) e183bc á„€ HANGUL CHOSEONG KIYEOK (U+1100) e18480 á„ HANGUL CHOSEONG SSANGKIYEOK (U+1101) e18481 á„‚ HANGUL CHOSEONG NIEUN (U+1102) e18482 ᄃ HANGUL CHOSEONG TIKEUT (U+1103) e18483 á„„ HANGUL CHOSEONG SSANGTIKEUT (U+1104) e18484 á„… HANGUL CHOSEONG RIEUL (U+1105) e18485 ᄆ HANGUL CHOSEONG MIEUM (U+1106) e18486 ᄇ HANGUL CHOSEONG PIEUP (U+1107) e18487 ᄈ HANGUL CHOSEONG SSANGPIEUP (U+1108) e18488 ᄉ HANGUL CHOSEONG SIOS (U+1109) e18489 ᄊ HANGUL CHOSEONG SSANGSIOS (U+110A) e1848a á„‹ HANGUL CHOSEONG IEUNG (U+110B) e1848b ᄌ HANGUL CHOSEONG CIEUC (U+110C) e1848c á„ HANGUL CHOSEONG SSANGCIEUC (U+110D) e1848d ᄎ HANGUL CHOSEONG CHIEUCH (U+110E) e1848e á„ HANGUL CHOSEONG KHIEUKH (U+110F) e1848f á„ HANGUL CHOSEONG THIEUTH (U+1110) e18490 á„‘ HANGUL CHOSEONG PHIEUPH (U+1111) e18491 á„’ HANGUL CHOSEONG HIEUH (U+1112) e18492 á„“ HANGUL CHOSEONG NIEUN-KIYEOK (U+1113) e18493 á„” HANGUL CHOSEONG SSANGNIEUN (U+1114) e18494 á„• HANGUL CHOSEONG NIEUN-TIKEUT (U+1115) e18495 á„– HANGUL CHOSEONG NIEUN-PIEUP (U+1116) e18496 á„— HANGUL CHOSEONG TIKEUT-KIYEOK (U+1117) e18497 ᄘ HANGUL CHOSEONG RIEUL-NIEUN (U+1118) e18498 á„™ HANGUL CHOSEONG SSANGRIEUL (U+1119) e18499 ᄚ HANGUL CHOSEONG RIEUL-HIEUH (U+111A) e1849a á„› HANGUL CHOSEONG KAPYEOUNRIEUL (U+111B) e1849b ᄜ HANGUL CHOSEONG MIEUM-PIEUP (U+111C) e1849c á„ HANGUL CHOSEONG KAPYEOUNMIEUM (U+111D) e1849d ᄞ HANGUL CHOSEONG PIEUP-KIYEOK (U+111E) e1849e ᄟ HANGUL CHOSEONG PIEUP-NIEUN (U+111F) e1849f á„  HANGUL CHOSEONG PIEUP-TIKEUT (U+1120) e184a0 á„¡ HANGUL CHOSEONG PIEUP-SIOS (U+1121) e184a1 á„¢ HANGUL CHOSEONG PIEUP-SIOS-KIYEOK (U+1122) e184a2 á„£ HANGUL CHOSEONG PIEUP-SIOS-TIKEUT (U+1123) e184a3 ᄤ HANGUL CHOSEONG PIEUP-SIOS-PIEUP (U+1124) e184a4 á„¥ HANGUL CHOSEONG PIEUP-SSANGSIOS (U+1125) e184a5 ᄦ HANGUL CHOSEONG PIEUP-SIOS-CIEUC (U+1126) e184a6 á„§ HANGUL CHOSEONG PIEUP-CIEUC (U+1127) e184a7 ᄨ HANGUL CHOSEONG PIEUP-CHIEUCH (U+1128) e184a8 á„© HANGUL CHOSEONG PIEUP-THIEUTH (U+1129) e184a9 ᄪ HANGUL CHOSEONG PIEUP-PHIEUPH (U+112A) e184aa á„« HANGUL CHOSEONG KAPYEOUNPIEUP (U+112B) e184ab ᄬ HANGUL CHOSEONG KAPYEOUNSSANGPIEUP (U+112C) e184ac á„­ HANGUL CHOSEONG SIOS-KIYEOK (U+112D) e184ad á„® HANGUL CHOSEONG SIOS-NIEUN (U+112E) e184ae ᄯ HANGUL CHOSEONG SIOS-TIKEUT (U+112F) e184af á„° HANGUL CHOSEONG SIOS-RIEUL (U+1130) e184b0 ᄱ HANGUL CHOSEONG SIOS-MIEUM (U+1131) e184b1 ᄲ HANGUL CHOSEONG SIOS-PIEUP (U+1132) e184b2 ᄳ HANGUL CHOSEONG SIOS-PIEUP-KIYEOK (U+1133) e184b3 á„´ HANGUL CHOSEONG SIOS-SSANGSIOS (U+1134) e184b4 ᄵ HANGUL CHOSEONG SIOS-IEUNG (U+1135) e184b5 á„¶ HANGUL CHOSEONG SIOS-CIEUC (U+1136) e184b6 á„· HANGUL CHOSEONG SIOS-CHIEUCH (U+1137) e184b7 ᄸ HANGUL CHOSEONG SIOS-KHIEUKH (U+1138) e184b8 ᄹ HANGUL CHOSEONG SIOS-THIEUTH (U+1139) e184b9 ᄺ HANGUL CHOSEONG SIOS-PHIEUPH (U+113A) e184ba á„» HANGUL CHOSEONG SIOS-HIEUH (U+113B) e184bb ᄼ HANGUL CHOSEONG CHITUEUMSIOS (U+113C) e184bc ᄽ HANGUL CHOSEONG CHITUEUMSSANGSIOS (U+113D) e184bd ᄾ HANGUL CHOSEONG CEONGCHIEUMSIOS (U+113E) e184be á„¿ HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS (U+113F) e184bf á…€ HANGUL CHOSEONG PANSIOS (U+1140) e18580 á… HANGUL CHOSEONG IEUNG-KIYEOK (U+1141) e18581 á…‚ HANGUL CHOSEONG IEUNG-TIKEUT (U+1142) e18582 á…ƒ HANGUL CHOSEONG IEUNG-MIEUM (U+1143) e18583 á…„ HANGUL CHOSEONG IEUNG-PIEUP (U+1144) e18584 á…… HANGUL CHOSEONG IEUNG-SIOS (U+1145) e18585 á…† HANGUL CHOSEONG IEUNG-PANSIOS (U+1146) e18586 á…‡ HANGUL CHOSEONG SSANGIEUNG (U+1147) e18587 á…ˆ HANGUL CHOSEONG IEUNG-CIEUC (U+1148) e18588 á…‰ HANGUL CHOSEONG IEUNG-CHIEUCH (U+1149) e18589 á…Š HANGUL CHOSEONG IEUNG-THIEUTH (U+114A) e1858a á…‹ HANGUL CHOSEONG IEUNG-PHIEUPH (U+114B) e1858b á…Œ HANGUL CHOSEONG YESIEUNG (U+114C) e1858c á… HANGUL CHOSEONG CIEUC-IEUNG (U+114D) e1858d á…Ž HANGUL CHOSEONG CHITUEUMCIEUC (U+114E) e1858e á… HANGUL CHOSEONG CHITUEUMSSANGCIEUC (U+114F) e1858f á… HANGUL CHOSEONG CEONGCHIEUMCIEUC (U+1150) e18590 á…‘ HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC (U+1151) e18591 á…’ HANGUL CHOSEONG CHIEUCH-KHIEUKH (U+1152) e18592 á…“ HANGUL CHOSEONG CHIEUCH-HIEUH (U+1153) e18593 á…” HANGUL CHOSEONG CHITUEUMCHIEUCH (U+1154) e18594 á…• HANGUL CHOSEONG CEONGCHIEUMCHIEUCH (U+1155) e18595 á…– HANGUL CHOSEONG PHIEUPH-PIEUP (U+1156) e18596 á…— HANGUL CHOSEONG KAPYEOUNPHIEUPH (U+1157) e18597 á…˜ HANGUL CHOSEONG SSANGHIEUH (U+1158) e18598 á…™ HANGUL CHOSEONG YEORINHIEUH (U+1159) e18599 á…š HANGUL CHOSEONG KIYEOK-TIKEUT (U+115A) e1859a á…› HANGUL CHOSEONG NIEUN-SIOS (U+115B) e1859b á…œ HANGUL CHOSEONG NIEUN-CIEUC (U+115C) e1859c á… HANGUL CHOSEONG NIEUN-HIEUH (U+115D) e1859d á…ž HANGUL CHOSEONG TIKEUT-RIEUL (U+115E) e1859e á…Ÿ HANGUL CHOSEONG FILLER (U+115F) e1859f á…  HANGUL JUNGSEONG FILLER (U+1160) e185a0 á…¡ HANGUL JUNGSEONG A (U+1161) e185a1 á…¢ HANGUL JUNGSEONG AE (U+1162) e185a2 á…£ HANGUL JUNGSEONG YA (U+1163) e185a3 á…¤ HANGUL JUNGSEONG YAE (U+1164) e185a4 á…¥ HANGUL JUNGSEONG EO (U+1165) e185a5 á…¦ HANGUL JUNGSEONG E (U+1166) e185a6 á…§ HANGUL JUNGSEONG YEO (U+1167) e185a7 á…¨ HANGUL JUNGSEONG YE (U+1168) e185a8 á…© HANGUL JUNGSEONG O (U+1169) e185a9 á…ª HANGUL JUNGSEONG WA (U+116A) e185aa á…« HANGUL JUNGSEONG WAE (U+116B) e185ab á…¬ HANGUL JUNGSEONG OE (U+116C) e185ac á…­ HANGUL JUNGSEONG YO (U+116D) e185ad á…® HANGUL JUNGSEONG U (U+116E) e185ae á…¯ HANGUL JUNGSEONG WEO (U+116F) e185af á…° HANGUL JUNGSEONG WE (U+1170) e185b0 á…± HANGUL JUNGSEONG WI (U+1171) e185b1 á…² HANGUL JUNGSEONG YU (U+1172) e185b2 á…³ HANGUL JUNGSEONG EU (U+1173) e185b3 á…´ HANGUL JUNGSEONG YI (U+1174) e185b4 á…µ HANGUL JUNGSEONG I (U+1175) e185b5 á…¶ HANGUL JUNGSEONG A-O (U+1176) e185b6 á…· HANGUL JUNGSEONG A-U (U+1177) e185b7 á…¸ HANGUL JUNGSEONG YA-O (U+1178) e185b8 á…¹ HANGUL JUNGSEONG YA-YO (U+1179) e185b9 á…º HANGUL JUNGSEONG EO-O (U+117A) e185ba á…» HANGUL JUNGSEONG EO-U (U+117B) e185bb á…¼ HANGUL JUNGSEONG EO-EU (U+117C) e185bc á…½ HANGUL JUNGSEONG YEO-O (U+117D) e185bd á…¾ HANGUL JUNGSEONG YEO-U (U+117E) e185be á…¿ HANGUL JUNGSEONG O-EO (U+117F) e185bf ᆀ HANGUL JUNGSEONG O-E (U+1180) e18680 ᆠHANGUL JUNGSEONG O-YE (U+1181) e18681 ᆂ HANGUL JUNGSEONG O-O (U+1182) e18682 ᆃ HANGUL JUNGSEONG O-U (U+1183) e18683 ᆄ HANGUL JUNGSEONG YO-YA (U+1184) e18684 ᆅ HANGUL JUNGSEONG YO-YAE (U+1185) e18685 ᆆ HANGUL JUNGSEONG YO-YEO (U+1186) e18686 ᆇ HANGUL JUNGSEONG YO-O (U+1187) e18687 ᆈ HANGUL JUNGSEONG YO-I (U+1188) e18688 ᆉ HANGUL JUNGSEONG U-A (U+1189) e18689 ᆊ HANGUL JUNGSEONG U-AE (U+118A) e1868a ᆋ HANGUL JUNGSEONG U-EO-EU (U+118B) e1868b ᆌ HANGUL JUNGSEONG U-YE (U+118C) e1868c ᆠHANGUL JUNGSEONG U-U (U+118D) e1868d ᆎ HANGUL JUNGSEONG YU-A (U+118E) e1868e ᆠHANGUL JUNGSEONG YU-EO (U+118F) e1868f ᆠHANGUL JUNGSEONG YU-E (U+1190) e18690 ᆑ HANGUL JUNGSEONG YU-YEO (U+1191) e18691 ᆒ HANGUL JUNGSEONG YU-YE (U+1192) e18692 ᆓ HANGUL JUNGSEONG YU-U (U+1193) e18693 ᆔ HANGUL JUNGSEONG YU-I (U+1194) e18694 ᆕ HANGUL JUNGSEONG EU-U (U+1195) e18695 ᆖ HANGUL JUNGSEONG EU-EU (U+1196) e18696 ᆗ HANGUL JUNGSEONG YI-U (U+1197) e18697 ᆘ HANGUL JUNGSEONG I-A (U+1198) e18698 ᆙ HANGUL JUNGSEONG I-YA (U+1199) e18699 ᆚ HANGUL JUNGSEONG I-O (U+119A) e1869a ᆛ HANGUL JUNGSEONG I-U (U+119B) e1869b ᆜ HANGUL JUNGSEONG I-EU (U+119C) e1869c ᆠHANGUL JUNGSEONG I-ARAEA (U+119D) e1869d ᆞ HANGUL JUNGSEONG ARAEA (U+119E) e1869e ᆟ HANGUL JUNGSEONG ARAEA-EO (U+119F) e1869f ᆠ HANGUL JUNGSEONG ARAEA-U (U+11A0) e186a0 ᆡ HANGUL JUNGSEONG ARAEA-I (U+11A1) e186a1 ᆢ HANGUL JUNGSEONG SSANGARAEA (U+11A2) e186a2 ᆣ HANGUL JUNGSEONG A-EU (U+11A3) e186a3 ᆤ HANGUL JUNGSEONG YA-U (U+11A4) e186a4 ᆥ HANGUL JUNGSEONG YEO-YA (U+11A5) e186a5 ᆦ HANGUL JUNGSEONG O-YA (U+11A6) e186a6 ᆧ HANGUL JUNGSEONG O-YAE (U+11A7) e186a7 ᆨ HANGUL JONGSEONG KIYEOK (U+11A8) e186a8 ᆩ HANGUL JONGSEONG SSANGKIYEOK (U+11A9) e186a9 ᆪ HANGUL JONGSEONG KIYEOK-SIOS (U+11AA) e186aa ᆫ HANGUL JONGSEONG NIEUN (U+11AB) e186ab ᆬ HANGUL JONGSEONG NIEUN-CIEUC (U+11AC) e186ac ᆭ HANGUL JONGSEONG NIEUN-HIEUH (U+11AD) e186ad ᆮ HANGUL JONGSEONG TIKEUT (U+11AE) e186ae ᆯ HANGUL JONGSEONG RIEUL (U+11AF) e186af ᆰ HANGUL JONGSEONG RIEUL-KIYEOK (U+11B0) e186b0 ᆱ HANGUL JONGSEONG RIEUL-MIEUM (U+11B1) e186b1 ᆲ HANGUL JONGSEONG RIEUL-PIEUP (U+11B2) e186b2 ᆳ HANGUL JONGSEONG RIEUL-SIOS (U+11B3) e186b3 ᆴ HANGUL JONGSEONG RIEUL-THIEUTH (U+11B4) e186b4 ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH (U+11B5) e186b5 ᆶ HANGUL JONGSEONG RIEUL-HIEUH (U+11B6) e186b6 ᆷ HANGUL JONGSEONG MIEUM (U+11B7) e186b7 ᆸ HANGUL JONGSEONG PIEUP (U+11B8) e186b8 ᆹ HANGUL JONGSEONG PIEUP-SIOS (U+11B9) e186b9 ᆺ HANGUL JONGSEONG SIOS (U+11BA) e186ba ᆻ HANGUL JONGSEONG SSANGSIOS (U+11BB) e186bb ᆼ HANGUL JONGSEONG IEUNG (U+11BC) e186bc ᆽ HANGUL JONGSEONG CIEUC (U+11BD) e186bd ᆾ HANGUL JONGSEONG CHIEUCH (U+11BE) e186be ᆿ HANGUL JONGSEONG KHIEUKH (U+11BF) e186bf ᇀ HANGUL JONGSEONG THIEUTH (U+11C0) e18780 ᇠHANGUL JONGSEONG PHIEUPH (U+11C1) e18781 ᇂ HANGUL JONGSEONG HIEUH (U+11C2) e18782 ᇃ HANGUL JONGSEONG KIYEOK-RIEUL (U+11C3) e18783 ᇄ HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK (U+11C4) e18784 ᇅ HANGUL JONGSEONG NIEUN-KIYEOK (U+11C5) e18785 ᇆ HANGUL JONGSEONG NIEUN-TIKEUT (U+11C6) e18786 ᇇ HANGUL JONGSEONG NIEUN-SIOS (U+11C7) e18787 ᇈ HANGUL JONGSEONG NIEUN-PANSIOS (U+11C8) e18788 ᇉ HANGUL JONGSEONG NIEUN-THIEUTH (U+11C9) e18789 ᇊ HANGUL JONGSEONG TIKEUT-KIYEOK (U+11CA) e1878a ᇋ HANGUL JONGSEONG TIKEUT-RIEUL (U+11CB) e1878b ᇌ HANGUL JONGSEONG RIEUL-KIYEOK-SIOS (U+11CC) e1878c ᇠHANGUL JONGSEONG RIEUL-NIEUN (U+11CD) e1878d ᇎ HANGUL JONGSEONG RIEUL-TIKEUT (U+11CE) e1878e ᇠHANGUL JONGSEONG RIEUL-TIKEUT-HIEUH (U+11CF) e1878f ᇠHANGUL JONGSEONG SSANGRIEUL (U+11D0) e18790 ᇑ HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK (U+11D1) e18791 ᇒ HANGUL JONGSEONG RIEUL-MIEUM-SIOS (U+11D2) e18792 ᇓ HANGUL JONGSEONG RIEUL-PIEUP-SIOS (U+11D3) e18793 ᇔ HANGUL JONGSEONG RIEUL-PIEUP-HIEUH (U+11D4) e18794 ᇕ HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP (U+11D5) e18795 ᇖ HANGUL JONGSEONG RIEUL-SSANGSIOS (U+11D6) e18796 ᇗ HANGUL JONGSEONG RIEUL-PANSIOS (U+11D7) e18797 ᇘ HANGUL JONGSEONG RIEUL-KHIEUKH (U+11D8) e18798 ᇙ HANGUL JONGSEONG RIEUL-YEORINHIEUH (U+11D9) e18799 ᇚ HANGUL JONGSEONG MIEUM-KIYEOK (U+11DA) e1879a ᇛ HANGUL JONGSEONG MIEUM-RIEUL (U+11DB) e1879b ᇜ HANGUL JONGSEONG MIEUM-PIEUP (U+11DC) e1879c ᇠHANGUL JONGSEONG MIEUM-SIOS (U+11DD) e1879d ᇞ HANGUL JONGSEONG MIEUM-SSANGSIOS (U+11DE) e1879e ᇟ HANGUL JONGSEONG MIEUM-PANSIOS (U+11DF) e1879f ᇠ HANGUL JONGSEONG MIEUM-CHIEUCH (U+11E0) e187a0 ᇡ HANGUL JONGSEONG MIEUM-HIEUH (U+11E1) e187a1 ᇢ HANGUL JONGSEONG KAPYEOUNMIEUM (U+11E2) e187a2 ᇣ HANGUL JONGSEONG PIEUP-RIEUL (U+11E3) e187a3 ᇤ HANGUL JONGSEONG PIEUP-PHIEUPH (U+11E4) e187a4 ᇥ HANGUL JONGSEONG PIEUP-HIEUH (U+11E5) e187a5 ᇦ HANGUL JONGSEONG KAPYEOUNPIEUP (U+11E6) e187a6 ᇧ HANGUL JONGSEONG SIOS-KIYEOK (U+11E7) e187a7 ᇨ HANGUL JONGSEONG SIOS-TIKEUT (U+11E8) e187a8 ᇩ HANGUL JONGSEONG SIOS-RIEUL (U+11E9) e187a9 ᇪ HANGUL JONGSEONG SIOS-PIEUP (U+11EA) e187aa ᇫ HANGUL JONGSEONG PANSIOS (U+11EB) e187ab ᇬ HANGUL JONGSEONG IEUNG-KIYEOK (U+11EC) e187ac ᇭ HANGUL JONGSEONG IEUNG-SSANGKIYEOK (U+11ED) e187ad ᇮ HANGUL JONGSEONG SSANGIEUNG (U+11EE) e187ae ᇯ HANGUL JONGSEONG IEUNG-KHIEUKH (U+11EF) e187af ᇰ HANGUL JONGSEONG YESIEUNG (U+11F0) e187b0 ᇱ HANGUL JONGSEONG YESIEUNG-SIOS (U+11F1) e187b1 ᇲ HANGUL JONGSEONG YESIEUNG-PANSIOS (U+11F2) e187b2 ᇳ HANGUL JONGSEONG PHIEUPH-PIEUP (U+11F3) e187b3 ᇴ HANGUL JONGSEONG KAPYEOUNPHIEUPH (U+11F4) e187b4 ᇵ HANGUL JONGSEONG HIEUH-NIEUN (U+11F5) e187b5 ᇶ HANGUL JONGSEONG HIEUH-RIEUL (U+11F6) e187b6 ᇷ HANGUL JONGSEONG HIEUH-MIEUM (U+11F7) e187b7 ᇸ HANGUL JONGSEONG HIEUH-PIEUP (U+11F8) e187b8 ᇹ HANGUL JONGSEONG YEORINHIEUH (U+11F9) e187b9 ᇺ HANGUL JONGSEONG KIYEOK-NIEUN (U+11FA) e187ba ᇻ HANGUL JONGSEONG KIYEOK-PIEUP (U+11FB) e187bb ᇼ HANGUL JONGSEONG KIYEOK-CHIEUCH (U+11FC) e187bc ᇽ HANGUL JONGSEONG KIYEOK-KHIEUKH (U+11FD) e187bd ᇾ HANGUL JONGSEONG KIYEOK-HIEUH (U+11FE) e187be ᇿ HANGUL JONGSEONG SSANGNIEUN (U+11FF) e187bf ሀ ETHIOPIC SYLLABLE HA (U+1200) e18880 ሠETHIOPIC SYLLABLE HU (U+1201) e18881 ሂ ETHIOPIC SYLLABLE HI (U+1202) e18882 ሃ ETHIOPIC SYLLABLE HAA (U+1203) e18883 ሄ ETHIOPIC SYLLABLE HEE (U+1204) e18884 ህ ETHIOPIC SYLLABLE HE (U+1205) e18885 ሆ ETHIOPIC SYLLABLE HO (U+1206) e18886 ሇ ETHIOPIC SYLLABLE HOA (U+1207) e18887 ለ ETHIOPIC SYLLABLE LA (U+1208) e18888 ሉ ETHIOPIC SYLLABLE LU (U+1209) e18889 ሊ ETHIOPIC SYLLABLE LI (U+120A) e1888a ላ ETHIOPIC SYLLABLE LAA (U+120B) e1888b ሌ ETHIOPIC SYLLABLE LEE (U+120C) e1888c ሠETHIOPIC SYLLABLE LE (U+120D) e1888d ሎ ETHIOPIC SYLLABLE LO (U+120E) e1888e ሠETHIOPIC SYLLABLE LWA (U+120F) e1888f ሠETHIOPIC SYLLABLE HHA (U+1210) e18890 ሑ ETHIOPIC SYLLABLE HHU (U+1211) e18891 ሒ ETHIOPIC SYLLABLE HHI (U+1212) e18892 ሓ ETHIOPIC SYLLABLE HHAA (U+1213) e18893 ሔ ETHIOPIC SYLLABLE HHEE (U+1214) e18894 ሕ ETHIOPIC SYLLABLE HHE (U+1215) e18895 ሖ ETHIOPIC SYLLABLE HHO (U+1216) e18896 ሗ ETHIOPIC SYLLABLE HHWA (U+1217) e18897 መ ETHIOPIC SYLLABLE MA (U+1218) e18898 ሙ ETHIOPIC SYLLABLE MU (U+1219) e18899 ሚ ETHIOPIC SYLLABLE MI (U+121A) e1889a ማ ETHIOPIC SYLLABLE MAA (U+121B) e1889b ሜ ETHIOPIC SYLLABLE MEE (U+121C) e1889c ሠETHIOPIC SYLLABLE ME (U+121D) e1889d ሞ ETHIOPIC SYLLABLE MO (U+121E) e1889e ሟ ETHIOPIC SYLLABLE MWA (U+121F) e1889f ሠ ETHIOPIC SYLLABLE SZA (U+1220) e188a0 ሡ ETHIOPIC SYLLABLE SZU (U+1221) e188a1 ሢ ETHIOPIC SYLLABLE SZI (U+1222) e188a2 ሣ ETHIOPIC SYLLABLE SZAA (U+1223) e188a3 ሤ ETHIOPIC SYLLABLE SZEE (U+1224) e188a4 ሥ ETHIOPIC SYLLABLE SZE (U+1225) e188a5 ሦ ETHIOPIC SYLLABLE SZO (U+1226) e188a6 ሧ ETHIOPIC SYLLABLE SZWA (U+1227) e188a7 ረ ETHIOPIC SYLLABLE RA (U+1228) e188a8 ሩ ETHIOPIC SYLLABLE RU (U+1229) e188a9 ሪ ETHIOPIC SYLLABLE RI (U+122A) e188aa ራ ETHIOPIC SYLLABLE RAA (U+122B) e188ab ሬ ETHIOPIC SYLLABLE REE (U+122C) e188ac ር ETHIOPIC SYLLABLE RE (U+122D) e188ad ሮ ETHIOPIC SYLLABLE RO (U+122E) e188ae ሯ ETHIOPIC SYLLABLE RWA (U+122F) e188af ሰ ETHIOPIC SYLLABLE SA (U+1230) e188b0 ሱ ETHIOPIC SYLLABLE SU (U+1231) e188b1 ሲ ETHIOPIC SYLLABLE SI (U+1232) e188b2 ሳ ETHIOPIC SYLLABLE SAA (U+1233) e188b3 ሴ ETHIOPIC SYLLABLE SEE (U+1234) e188b4 ስ ETHIOPIC SYLLABLE SE (U+1235) e188b5 ሶ ETHIOPIC SYLLABLE SO (U+1236) e188b6 ሷ ETHIOPIC SYLLABLE SWA (U+1237) e188b7 ሸ ETHIOPIC SYLLABLE SHA (U+1238) e188b8 ሹ ETHIOPIC SYLLABLE SHU (U+1239) e188b9 ሺ ETHIOPIC SYLLABLE SHI (U+123A) e188ba ሻ ETHIOPIC SYLLABLE SHAA (U+123B) e188bb ሼ ETHIOPIC SYLLABLE SHEE (U+123C) e188bc ሽ ETHIOPIC SYLLABLE SHE (U+123D) e188bd ሾ ETHIOPIC SYLLABLE SHO (U+123E) e188be ሿ ETHIOPIC SYLLABLE SHWA (U+123F) e188bf ቀ ETHIOPIC SYLLABLE QA (U+1240) e18980 በETHIOPIC SYLLABLE QU (U+1241) e18981 ቂ ETHIOPIC SYLLABLE QI (U+1242) e18982 ቃ ETHIOPIC SYLLABLE QAA (U+1243) e18983 ቄ ETHIOPIC SYLLABLE QEE (U+1244) e18984 ቅ ETHIOPIC SYLLABLE QE (U+1245) e18985 ቆ ETHIOPIC SYLLABLE QO (U+1246) e18986 ቇ ETHIOPIC SYLLABLE QOA (U+1247) e18987 ቈ ETHIOPIC SYLLABLE QWA (U+1248) e18988 ቊ ETHIOPIC SYLLABLE QWI (U+124A) e1898a ቋ ETHIOPIC SYLLABLE QWAA (U+124B) e1898b ቌ ETHIOPIC SYLLABLE QWEE (U+124C) e1898c በETHIOPIC SYLLABLE QWE (U+124D) e1898d በETHIOPIC SYLLABLE QHA (U+1250) e18990 ቑ ETHIOPIC SYLLABLE QHU (U+1251) e18991 ቒ ETHIOPIC SYLLABLE QHI (U+1252) e18992 ቓ ETHIOPIC SYLLABLE QHAA (U+1253) e18993 ቔ ETHIOPIC SYLLABLE QHEE (U+1254) e18994 ቕ ETHIOPIC SYLLABLE QHE (U+1255) e18995 ቖ ETHIOPIC SYLLABLE QHO (U+1256) e18996 ቘ ETHIOPIC SYLLABLE QHWA (U+1258) e18998 ቚ ETHIOPIC SYLLABLE QHWI (U+125A) e1899a ቛ ETHIOPIC SYLLABLE QHWAA (U+125B) e1899b ቜ ETHIOPIC SYLLABLE QHWEE (U+125C) e1899c በETHIOPIC SYLLABLE QHWE (U+125D) e1899d በ ETHIOPIC SYLLABLE BA (U+1260) e189a0 ቡ ETHIOPIC SYLLABLE BU (U+1261) e189a1 ቢ ETHIOPIC SYLLABLE BI (U+1262) e189a2 ባ ETHIOPIC SYLLABLE BAA (U+1263) e189a3 ቤ ETHIOPIC SYLLABLE BEE (U+1264) e189a4 ብ ETHIOPIC SYLLABLE BE (U+1265) e189a5 ቦ ETHIOPIC SYLLABLE BO (U+1266) e189a6 ቧ ETHIOPIC SYLLABLE BWA (U+1267) e189a7 ቨ ETHIOPIC SYLLABLE VA (U+1268) e189a8 ቩ ETHIOPIC SYLLABLE VU (U+1269) e189a9 ቪ ETHIOPIC SYLLABLE VI (U+126A) e189aa ቫ ETHIOPIC SYLLABLE VAA (U+126B) e189ab ቬ ETHIOPIC SYLLABLE VEE (U+126C) e189ac ቭ ETHIOPIC SYLLABLE VE (U+126D) e189ad ቮ ETHIOPIC SYLLABLE VO (U+126E) e189ae ቯ ETHIOPIC SYLLABLE VWA (U+126F) e189af ተ ETHIOPIC SYLLABLE TA (U+1270) e189b0 ቱ ETHIOPIC SYLLABLE TU (U+1271) e189b1 ቲ ETHIOPIC SYLLABLE TI (U+1272) e189b2 ታ ETHIOPIC SYLLABLE TAA (U+1273) e189b3 ቴ ETHIOPIC SYLLABLE TEE (U+1274) e189b4 ት ETHIOPIC SYLLABLE TE (U+1275) e189b5 ቶ ETHIOPIC SYLLABLE TO (U+1276) e189b6 ቷ ETHIOPIC SYLLABLE TWA (U+1277) e189b7 ቸ ETHIOPIC SYLLABLE CA (U+1278) e189b8 ቹ ETHIOPIC SYLLABLE CU (U+1279) e189b9 ቺ ETHIOPIC SYLLABLE CI (U+127A) e189ba ቻ ETHIOPIC SYLLABLE CAA (U+127B) e189bb ቼ ETHIOPIC SYLLABLE CEE (U+127C) e189bc ች ETHIOPIC SYLLABLE CE (U+127D) e189bd ቾ ETHIOPIC SYLLABLE CO (U+127E) e189be ቿ ETHIOPIC SYLLABLE CWA (U+127F) e189bf ኀ ETHIOPIC SYLLABLE XA (U+1280) e18a80 አETHIOPIC SYLLABLE XU (U+1281) e18a81 ኂ ETHIOPIC SYLLABLE XI (U+1282) e18a82 ኃ ETHIOPIC SYLLABLE XAA (U+1283) e18a83 ኄ ETHIOPIC SYLLABLE XEE (U+1284) e18a84 ኅ ETHIOPIC SYLLABLE XE (U+1285) e18a85 ኆ ETHIOPIC SYLLABLE XO (U+1286) e18a86 ኇ ETHIOPIC SYLLABLE XOA (U+1287) e18a87 ኈ ETHIOPIC SYLLABLE XWA (U+1288) e18a88 ኊ ETHIOPIC SYLLABLE XWI (U+128A) e18a8a ኋ ETHIOPIC SYLLABLE XWAA (U+128B) e18a8b ኌ ETHIOPIC SYLLABLE XWEE (U+128C) e18a8c አETHIOPIC SYLLABLE XWE (U+128D) e18a8d አETHIOPIC SYLLABLE NA (U+1290) e18a90 ኑ ETHIOPIC SYLLABLE NU (U+1291) e18a91 ኒ ETHIOPIC SYLLABLE NI (U+1292) e18a92 ና ETHIOPIC SYLLABLE NAA (U+1293) e18a93 ኔ ETHIOPIC SYLLABLE NEE (U+1294) e18a94 ን ETHIOPIC SYLLABLE NE (U+1295) e18a95 ኖ ETHIOPIC SYLLABLE NO (U+1296) e18a96 ኗ ETHIOPIC SYLLABLE NWA (U+1297) e18a97 ኘ ETHIOPIC SYLLABLE NYA (U+1298) e18a98 ኙ ETHIOPIC SYLLABLE NYU (U+1299) e18a99 ኚ ETHIOPIC SYLLABLE NYI (U+129A) e18a9a ኛ ETHIOPIC SYLLABLE NYAA (U+129B) e18a9b ኜ ETHIOPIC SYLLABLE NYEE (U+129C) e18a9c አETHIOPIC SYLLABLE NYE (U+129D) e18a9d ኞ ETHIOPIC SYLLABLE NYO (U+129E) e18a9e ኟ ETHIOPIC SYLLABLE NYWA (U+129F) e18a9f አ ETHIOPIC SYLLABLE GLOTTAL A (U+12A0) e18aa0 ኡ ETHIOPIC SYLLABLE GLOTTAL U (U+12A1) e18aa1 ኢ ETHIOPIC SYLLABLE GLOTTAL I (U+12A2) e18aa2 ኣ ETHIOPIC SYLLABLE GLOTTAL AA (U+12A3) e18aa3 ኤ ETHIOPIC SYLLABLE GLOTTAL EE (U+12A4) e18aa4 እ ETHIOPIC SYLLABLE GLOTTAL E (U+12A5) e18aa5 ኦ ETHIOPIC SYLLABLE GLOTTAL O (U+12A6) e18aa6 ኧ ETHIOPIC SYLLABLE GLOTTAL WA (U+12A7) e18aa7 ከ ETHIOPIC SYLLABLE KA (U+12A8) e18aa8 ኩ ETHIOPIC SYLLABLE KU (U+12A9) e18aa9 ኪ ETHIOPIC SYLLABLE KI (U+12AA) e18aaa ካ ETHIOPIC SYLLABLE KAA (U+12AB) e18aab ኬ ETHIOPIC SYLLABLE KEE (U+12AC) e18aac ክ ETHIOPIC SYLLABLE KE (U+12AD) e18aad ኮ ETHIOPIC SYLLABLE KO (U+12AE) e18aae ኯ ETHIOPIC SYLLABLE KOA (U+12AF) e18aaf ኰ ETHIOPIC SYLLABLE KWA (U+12B0) e18ab0 ኲ ETHIOPIC SYLLABLE KWI (U+12B2) e18ab2 ኳ ETHIOPIC SYLLABLE KWAA (U+12B3) e18ab3 ኴ ETHIOPIC SYLLABLE KWEE (U+12B4) e18ab4 ኵ ETHIOPIC SYLLABLE KWE (U+12B5) e18ab5 ኸ ETHIOPIC SYLLABLE KXA (U+12B8) e18ab8 ኹ ETHIOPIC SYLLABLE KXU (U+12B9) e18ab9 ኺ ETHIOPIC SYLLABLE KXI (U+12BA) e18aba ኻ ETHIOPIC SYLLABLE KXAA (U+12BB) e18abb ኼ ETHIOPIC SYLLABLE KXEE (U+12BC) e18abc ኽ ETHIOPIC SYLLABLE KXE (U+12BD) e18abd ኾ ETHIOPIC SYLLABLE KXO (U+12BE) e18abe á‹€ ETHIOPIC SYLLABLE KXWA (U+12C0) e18b80 á‹‚ ETHIOPIC SYLLABLE KXWI (U+12C2) e18b82 ዃ ETHIOPIC SYLLABLE KXWAA (U+12C3) e18b83 á‹„ ETHIOPIC SYLLABLE KXWEE (U+12C4) e18b84 á‹… ETHIOPIC SYLLABLE KXWE (U+12C5) e18b85 ወ ETHIOPIC SYLLABLE WA (U+12C8) e18b88 ዉ ETHIOPIC SYLLABLE WU (U+12C9) e18b89 ዊ ETHIOPIC SYLLABLE WI (U+12CA) e18b8a á‹‹ ETHIOPIC SYLLABLE WAA (U+12CB) e18b8b ዌ ETHIOPIC SYLLABLE WEE (U+12CC) e18b8c á‹ ETHIOPIC SYLLABLE WE (U+12CD) e18b8d ዎ ETHIOPIC SYLLABLE WO (U+12CE) e18b8e á‹ ETHIOPIC SYLLABLE WOA (U+12CF) e18b8f á‹ ETHIOPIC SYLLABLE PHARYNGEAL A (U+12D0) e18b90 á‹‘ ETHIOPIC SYLLABLE PHARYNGEAL U (U+12D1) e18b91 á‹’ ETHIOPIC SYLLABLE PHARYNGEAL I (U+12D2) e18b92 á‹“ ETHIOPIC SYLLABLE PHARYNGEAL AA (U+12D3) e18b93 á‹” ETHIOPIC SYLLABLE PHARYNGEAL EE (U+12D4) e18b94 á‹• ETHIOPIC SYLLABLE PHARYNGEAL E (U+12D5) e18b95 á‹– ETHIOPIC SYLLABLE PHARYNGEAL O (U+12D6) e18b96 ዘ ETHIOPIC SYLLABLE ZA (U+12D8) e18b98 á‹™ ETHIOPIC SYLLABLE ZU (U+12D9) e18b99 ዚ ETHIOPIC SYLLABLE ZI (U+12DA) e18b9a á‹› ETHIOPIC SYLLABLE ZAA (U+12DB) e18b9b ዜ ETHIOPIC SYLLABLE ZEE (U+12DC) e18b9c á‹ ETHIOPIC SYLLABLE ZE (U+12DD) e18b9d ዞ ETHIOPIC SYLLABLE ZO (U+12DE) e18b9e ዟ ETHIOPIC SYLLABLE ZWA (U+12DF) e18b9f á‹  ETHIOPIC SYLLABLE ZHA (U+12E0) e18ba0 á‹¡ ETHIOPIC SYLLABLE ZHU (U+12E1) e18ba1 á‹¢ ETHIOPIC SYLLABLE ZHI (U+12E2) e18ba2 á‹£ ETHIOPIC SYLLABLE ZHAA (U+12E3) e18ba3 ዤ ETHIOPIC SYLLABLE ZHEE (U+12E4) e18ba4 á‹¥ ETHIOPIC SYLLABLE ZHE (U+12E5) e18ba5 ዦ ETHIOPIC SYLLABLE ZHO (U+12E6) e18ba6 á‹§ ETHIOPIC SYLLABLE ZHWA (U+12E7) e18ba7 የ ETHIOPIC SYLLABLE YA (U+12E8) e18ba8 á‹© ETHIOPIC SYLLABLE YU (U+12E9) e18ba9 ዪ ETHIOPIC SYLLABLE YI (U+12EA) e18baa á‹« ETHIOPIC SYLLABLE YAA (U+12EB) e18bab ዬ ETHIOPIC SYLLABLE YEE (U+12EC) e18bac á‹­ ETHIOPIC SYLLABLE YE (U+12ED) e18bad á‹® ETHIOPIC SYLLABLE YO (U+12EE) e18bae ዯ ETHIOPIC SYLLABLE YOA (U+12EF) e18baf á‹° ETHIOPIC SYLLABLE DA (U+12F0) e18bb0 ዱ ETHIOPIC SYLLABLE DU (U+12F1) e18bb1 ዲ ETHIOPIC SYLLABLE DI (U+12F2) e18bb2 ዳ ETHIOPIC SYLLABLE DAA (U+12F3) e18bb3 á‹´ ETHIOPIC SYLLABLE DEE (U+12F4) e18bb4 ድ ETHIOPIC SYLLABLE DE (U+12F5) e18bb5 á‹¶ ETHIOPIC SYLLABLE DO (U+12F6) e18bb6 á‹· ETHIOPIC SYLLABLE DWA (U+12F7) e18bb7 ዸ ETHIOPIC SYLLABLE DDA (U+12F8) e18bb8 ዹ ETHIOPIC SYLLABLE DDU (U+12F9) e18bb9 ዺ ETHIOPIC SYLLABLE DDI (U+12FA) e18bba á‹» ETHIOPIC SYLLABLE DDAA (U+12FB) e18bbb ዼ ETHIOPIC SYLLABLE DDEE (U+12FC) e18bbc ዽ ETHIOPIC SYLLABLE DDE (U+12FD) e18bbd ዾ ETHIOPIC SYLLABLE DDO (U+12FE) e18bbe á‹¿ ETHIOPIC SYLLABLE DDWA (U+12FF) e18bbf ጀ ETHIOPIC SYLLABLE JA (U+1300) e18c80 ጠETHIOPIC SYLLABLE JU (U+1301) e18c81 ጂ ETHIOPIC SYLLABLE JI (U+1302) e18c82 ጃ ETHIOPIC SYLLABLE JAA (U+1303) e18c83 ጄ ETHIOPIC SYLLABLE JEE (U+1304) e18c84 ጅ ETHIOPIC SYLLABLE JE (U+1305) e18c85 ጆ ETHIOPIC SYLLABLE JO (U+1306) e18c86 ጇ ETHIOPIC SYLLABLE JWA (U+1307) e18c87 ገ ETHIOPIC SYLLABLE GA (U+1308) e18c88 ጉ ETHIOPIC SYLLABLE GU (U+1309) e18c89 ጊ ETHIOPIC SYLLABLE GI (U+130A) e18c8a ጋ ETHIOPIC SYLLABLE GAA (U+130B) e18c8b ጌ ETHIOPIC SYLLABLE GEE (U+130C) e18c8c ጠETHIOPIC SYLLABLE GE (U+130D) e18c8d ጎ ETHIOPIC SYLLABLE GO (U+130E) e18c8e ጠETHIOPIC SYLLABLE GOA (U+130F) e18c8f ጠETHIOPIC SYLLABLE GWA (U+1310) e18c90 ጒ ETHIOPIC SYLLABLE GWI (U+1312) e18c92 ጓ ETHIOPIC SYLLABLE GWAA (U+1313) e18c93 ጔ ETHIOPIC SYLLABLE GWEE (U+1314) e18c94 ጕ ETHIOPIC SYLLABLE GWE (U+1315) e18c95 ጘ ETHIOPIC SYLLABLE GGA (U+1318) e18c98 ጙ ETHIOPIC SYLLABLE GGU (U+1319) e18c99 ጚ ETHIOPIC SYLLABLE GGI (U+131A) e18c9a ጛ ETHIOPIC SYLLABLE GGAA (U+131B) e18c9b ጜ ETHIOPIC SYLLABLE GGEE (U+131C) e18c9c ጠETHIOPIC SYLLABLE GGE (U+131D) e18c9d ጞ ETHIOPIC SYLLABLE GGO (U+131E) e18c9e ጟ ETHIOPIC SYLLABLE GGWAA (U+131F) e18c9f ጠ ETHIOPIC SYLLABLE THA (U+1320) e18ca0 ጡ ETHIOPIC SYLLABLE THU (U+1321) e18ca1 ጢ ETHIOPIC SYLLABLE THI (U+1322) e18ca2 ጣ ETHIOPIC SYLLABLE THAA (U+1323) e18ca3 ጤ ETHIOPIC SYLLABLE THEE (U+1324) e18ca4 ጥ ETHIOPIC SYLLABLE THE (U+1325) e18ca5 ጦ ETHIOPIC SYLLABLE THO (U+1326) e18ca6 ጧ ETHIOPIC SYLLABLE THWA (U+1327) e18ca7 More... ’ XML-Smart-1.78/data_for_tests/winSpecial.data0000644000175000017500000000003312101730313020430 0ustar harishharish" ‘ ’ †“ – … XML-Smart-1.78/data_for_tests/German.data0000644000175000017500000000012012101730313017540 0ustar harishharishDer alte Mann hat mir heute das Buch gegeben A Ä E I O Ö U Ü Geländesprung XML-Smart-1.78/data_for_tests/Chinese.data0000644000175000017500000000024512101730313017715 0ustar harishharish汉语/漢語 HànyÇ”;åŽè¯­è¯èªžHuáyÇ”;中文ZhÅngwén官è¯åŒ—æ–¹è¯ç²µèªž 語 廣西平話徽 妈 骂中国ï¼ä¸­åœ‹æ¯›æ³½ä¸œï¼æ¯›æ¾¤æ±è’‹ä»‹çŸ³ï¼è”£ä»‹çŸ³ XML-Smart-1.78/data_for_tests/bug_andpersand.data0000644000175000017500000000017412101730313021314 0ustar harishharish**NEW TWITTER ACCOUNT.** #TeamFollowBack GetHigh'LiveRighteous;; Him&TheGirls;; 3Tats8Piercings (: No Shaiyons, No Fatties XML-Smart-1.78/data_for_tests/bug_arabic.data0000644000175000017500000000222712101730313020417 0ustar harishharishانشرها هام جدا رجاء نشر هذا الخبر ولا تجعله يق٠عندك عاجل اعترضت إيران على شركة جوجل لـتسميتها الخليج العربي بهذا الاسم وتطالب بان يسمى بالخليج Ø§Ù„ÙØ§Ø±Ø³ÙŠØŒ واستجابت جوجل لطلبها وعملت تصويت على الاسمين وقالت بأن الذي ستكون له النسبة الأكبر سيتم إدراجه ÙÙŠ (جوجل)ØŒ صوت قبل أن يتغير اسم الخليج العربي إلى الخليج Ø§Ù„ÙØ§Ø±Ø³ÙŠ Ù‡Ø°Ø§ رابط التصويت طريقة التصويت: Ø§ÙØªØ­ Ø§Ù„ØµÙØ­Ø© ستجد مربع ازرق صغير اضغط على (الخليج العربي) وبعدها اضغط على (vote) باقي 37 يوم علي انتهاء التصويت Voting is still open var AdBrite_Title_Color = '0000FF'; var AdBrite_Text_Color = '000000'; var AdBrite_Background_Color = 'FFFFFF'; var AdBrite_Border_Color = 'CCCCCC'; var AdBrite_URL_Color = '000000'; try{var AdBrite_Iframe=window.top!=window.self?2:1;var AdBrite_Referrer=document.referrer==''?do... XML-Smart-1.78/data_for_tests/Japanese.data0000644000175000017500000000123212101730313020062 0ustar harishharish日本語 (ã‚„ã£ãŸ! 驚ã„ãŸå½¼ã¯é“ã‚’èµ°ã£ã¦ã„ã£ãŸã€‚形容詞 keiyÅshi, or i adjectives, which have a conjugating ending i (ã„) (such as 暑ㄠatsui "to be hot") which can become past (æš‘ã‹ã£ãŸ atsukatta "it was hot"), or negative (æš‘ããªã„ atsuku nai "it is not hot"). Note that nai is also an i adjective, which can become past (æš‘ããªã‹ã£ãŸ atsuku nakatta "it was not hot"). ã® no for the genitive case, or nominalizing phrases. ç§ã®ã‚«ãƒ¡ãƒ©ã€‚ watashi no kamera "my camera" スキーã«è¡Œãã®ãŒå¥½ãã§ã™ã€‚ SukÄ«-ni iku no ga suki desu "(I) like going skiing." æªã€‚書åšå£«ç™¾æ¸ˆæœ«å£«å–„ä¿¡ã€éŠ€äººäºŒå両。 XML-Smart-1.78/data_for_tests/French.data0000644000175000017500000000013712101730313017544 0ustar harishharishFrançais Où Assez bien or Ça va comme ci, comme ça or simply Ça va.. Alliance française XML-Smart-1.78/data_for_tests/umlaut.data0000644000175000017500000001226712101730313017655 0ustar harishharishÄä Ëë Ḧḧ Ã ï N̈n̈ Öö T̈ẗ Üü Ẅẅ ẌẠŸÿ Ä ä Çž ÇŸ Ë ë Ḧ ḧ à ï Ḯ ḯ M̈ m̈ Ö ö Ȫ È« Ṏ á¹ P̈ p̈ T̈ ẗ Ü ü Ç• Ç– Ç— ǘ Ç™ Çš Ç› Çœ á¹² á¹³ Ṻ á¹» V̈ v̈ Ẅ ẅ Ẍ ẠŸ ÿ Å Å‘ Ű ű short a e i o ö u ü long á é í ó Å‘ ú ű a, à /a/ patte, arable, là /É‘/ araser, base ai /É›/ /e/ caisse, faite baisser, aiguille aie /É›/ baie aou /u/ saoul, Août au /o/ haut, augure /É”/ sauropode ay /ei/ pays e non-finally /e/ essence /É›/ /É™/ est, estival repeser /a/ solennel finally Ø caisse, unique /É™/ que é, ée /e/ clé, échapper, idée è /É›/ relève, zèle eau /o/ eau, oiseaux ei /É›/ neige, reine eu /ø/ ceux, peu /Å“/ jeune i elsewhere /i/ ici, proscrire before vowel /j/ fief, ionique, rien -ie /i/ régie o /É”/ opter, offre Å“ /Å“/ Å“il /e/ Å“sophage Å“u /Å“/ sÅ“ur, cÅ“ur oi, oie /wa/ roi, oiseau, foie /É”/ oignon ou elsewhere /u/ ouvrir, sous before vowel /w/ ouest, couiner, oui -oue /u/ roue oy /waj/ moyen, royaume u elsewhere /y/ tu, juge before vowel /É¥/ huit, tuer -ue /y/ rue y /i/ cyclone, style -ps, -ts, etc. Ø draps, achats b, bb elsewhere /b/ ballon, abbé next to voiceless consonant /p/ absolu ç /s/ ça, garçon c before e, i, y /s/ cyclone, loquace, accès elsewhere /k/ cabas, crasse, accord, lac Ø tabac cc before e, i, y /ks/ accès elsewhere /k/ accord ch /ʃ/ chat, douche /k/ chaotique, chlore cqu /k/ acquit, acquéreur d, dd non-finally /d/ doux, adresse, addition finally Ø pied, accord f, ff /f/ fait, affoler g, gg before e, i, y /Ê’/ gens, manger, suggérer elsewhere /É¡/ gain, glacier, aggravé gn /ɲ/ montagne, agneau h Ø habite, hiver j /Ê’/ joue, jeter l, ll non-finally /l/ lait, allier finally Ø fusil, m, mm /m/ mou, pomme n, nn /n/ nouvel, panne ng /Å‹/ parking, camping p, pp non-finally /p/ pain, appel finally Ø corp, trop ph /f/ téléphone, photo r, rr /Ê/ rat, barre s initially or next to a voiceless consonant /s/ sacre, estime medially elsewhere /z/ rose, paysage finally Ø dans, repas sc before e, i, y /s/ science elsewhere /sk/ script ss /s/ baisser, passer t, tt non-finally /t/ tout, attente finally Ø tant, raffut /t/ est (direction) th /t/ thème, thermique v /v/ ville, vanne x next to a voiceless consonant /ks/ expansion medially elsewhere /É¡z/ exigence, exulter /s/ /z/ soixante deuxième finally Ø paix, deux /s/ six, dix xc before e, i, y /ks/ exciter elsewhere /ksk/ excavation y /j/ yeux, yole z non-finally /z/ zain, gazette finally Ø chez /z/ gaz Spelling Major value (IPA) Examples of major value Minor values (IPA) Examples of minor value Exceptions aim, ain (before consonant or finally) /ɛ̃/ faim, saint, bains am, an, ang (before consonant or finally) /ɑ̃/ ambiance, France, sang aon (before consonant or finally) /ɑ̃/ paon ein (before consonant or finally) /ɛ̃/ plein, vin, vingt em, en (before consonant or finally) /ɑ̃/ embaucher, vent -er /e/ aller, transporter /É›Ê/ hiver -es Ø Nantes, faites ge /Ê’/ geai, mangea gu /É¡/ guerre ien (before consonant or finally) /jɛ̃/ rien, chien -il (after vowel) /j/ ail, conseil -il (not after vowel) /il/ il, fil /i/ outil, fils, fusil -ill- (after vowel) /j/ paille, nouille -ill- (not after vowel) /ij/ grillage, bille /il/ million, village, ville im, in, ing (before consonant or finally) /ɛ̃/ importer, vin, vingt oin, oing (before consonant or finally) /wɛ̃/ point, poing om, on (before consonant or finally) /ɔ̃/ ombre, bon qu /k/ quand, pourquoi um, un (before consonant or finally) /œ̃/ parfum, brun ym, yn (before consonant or finally) /ɛ̃/ sympa, syndrome XML-Smart-1.78/data_for_tests/Russian.data0000644000175000017500000000012312101730313017756 0ustar harishharishÐБВГДЕÐЖЗИЙКЛМÐОПРСТУФХЦЧШʂЩɕɕЪ-ЫɨЬʲЭeЮjuЯja XML-Smart-1.78/data_for_tests/Portuguese.data0000644000175000017500000000350712101730313020505 0ustar harishharishOriginal IPA (Lisbon) IPA (São Paulo) IPA (Santiago de Compostela) Translation Sustentava contra ele Vénus bela, suʃtẽˈtavÉ ËˆkõtÉ¾É Ëˆelɨ ˈvÉ›nuÊ’ ˈβɛlÉ sustẽˈtavÉ ËˆkõtÉ¾É Ëˆeli ˈvenuz ˈbÉ›lÉ sustenˈtaβa ˈkontɾa ˈel ˈβɛnuz ˈβɛla Held against him the lovely Venus Afeiçoada à gente Lusitana, ÉfÉjsuˈaða ˈʒẽtɨ luziˈtÉnÉ afejsuˈada ˈʒẽtʃi luziˈtÉnÉ afejθoˈaða ˈʃente lusiˈtana Fondly to the people of Portugal, Por quantas qualidades via nela puɾ ˈkwÉ̃tÉʃ kwÉliˈðaðɨʒ ˈviÉ ËˆnÉ›lÉ puɾ ˈkwÉ̃tÉs kwaliˈdadÊ’iz ˈviÉ ËˆnÉ›lÉ poɾ ˈkantas kwaliˈðaðez ˈβia ˈnÉ›la For many qualities he saw in her Da antiga tão amada sua Romana; dÉ̃ˈtiÉ£É ËˆtÉ̃w̃ ÉˈmaÃ°É ËˆsuÉ ÊuˈmÉnÉ dÉ̃ˈtʃiÉ¡É ËˆtÉ̃w̃ ÉˈmadÉ ËˆsuÉ hoˈmÉnÉ danˈtiÉ£a ˈtaÅ‹ aˈmaða ˈsua roˈmana From his old beloved Roman; Nos fortes corações, na grande estrela, nuʃ ˈfɔɾtɨʃ kuɾÉˈsõj̃ʃ nÉ ËŒÉ£É¾É̃dɨʃˈtɾelÉ nus ˈfɔɾtʃis koɾaˈsõj̃s na ˌɡɾÉ̃dÊ’isˈtɾelÉ nos ˈfɔɾtes koɾaˈθons na ˌɣɾandesˈtɾela In the stout hearts, in the big star Que mostraram na terra Tingitana, kɨ muʃˈtɾaɾÉ̃w̃ nÉ ËˆtÉ›ÊÉ tĩʒiˈtÉnÉ ki mosˈtɾaɾÉ̃w̃ na ˈtÉ›hÉ tʃĩʒiˈtÉnÉ ke mosˈtɾaraÅ‹ na ˈtÉ›ra tinʃiˈtana That showed in the land Tingitana, E na língua, na qual quando imagina, i nÉ ËˆlĩɡwÉ nÉ ËˆkwaÉ« ˈkwÉ̃du jmÉˈʒinÉ i na ˈlĩɡwÉ na ˈkwaw ˈkwÉ̃dimaˈʒinÉ e na ˈliÅ‹gwa na ˈkal ˈkando jmaˈʃina And in the language, which when it is imagined Com pouca corrupção crê que é a Latina. kõ ˈpokÉ kuÊupˈsÉ̃w̃ ˈkɾe kiˈɛ É lÉˈtinÉ kÅ© ˈpokÉ kohup(i)ˈsÉ̃w̃ ˈkɾe kiˈɛ a laˈtʃinÉ kom ˈpowka korupˈθ(j)oÅ‹ ˈkɾe ˈkÉ› a laˈtina With little corruption, believes that it is Latin.[79] XML-Smart-1.78/data_for_tests/URLChars.data0000644000175000017500000000004712101730313017762 0ustar harishharishL (Néry) Battery Royal Horse ArtilleryXML-Smart-1.78/lib/0000755000175000017500000000000012214355545013267 5ustar harishharishXML-Smart-1.78/lib/XML/0000755000175000017500000000000012214355545013727 5ustar harishharishXML-Smart-1.78/lib/XML/Smart/0000755000175000017500000000000012214355545015015 5ustar harishharishXML-Smart-1.78/lib/XML/Smart/Tutorial.pod0000644000175000017500000001163012103722204017310 0ustar harishharish =head1 NAME XML::Smart::Tutorial - Tutorial and examples for XML::Smart. =head1 SYNOPSIS This document is a tutorial for I and shows some examples of usual things. =head1 Working with contents: In I the key I is reserved and shouldn't be used directly, since I will deal with the convertion of arguments to node contents, including multiple node contents autimatically. =head2 What happens when you set a value: $xml->{root}{foo} = 'simple value' ; Here foo will be a normal argument/attribute value, and will generate this XML data: But if you insert some tag or lines in the values by default I will convert it to a node content: $xml->{root}{foo} = "line0\nlien1\nline2\n" ; And will generate that XML data: line0 lien1 line2 But what you can do if you want to force some type, let's say, have a node content with a simple value: $xml->{root}{foo} = 'simple value' ; $xml->{root}{foo}->set_node(1) ; And will generate that XML data: simple value =head2 Multiple contents: When you have interpolated content/data you need to work in a different. Let's say that you load this XML data: content0 content1 If you access directly the root key as string you will get all the content parts grouped. So, this code: my $xml = new XML::Smart(q` content0 content1 `,'smart') ; print "#$xml->{root}#" ; Will print that: # content0 content1 # B:> my @content = $xml->{root}->content ; print "#$content[0]#\n" ; And this will print that: # content0 # B with 2 arguments:> $xml->{root}->content(0,'new content') ; And now the XML data produced will be: new content content1 If you use the method I with only one argument it will remove all the multiple contents and will set the new value in the place of the 1st content. =head1 Setting the XML Parser. By defaul I will use L or L (in this order of preference) to load a XML data. To force or define by your self the parser you can use the 2nd argument option when creating a I object: my $xml = new XML::Smart( 'some.xml' , 'XML::Parser' ) ; ## and my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::Parser' ) ; I also has an extra parser, I, that can be used to load HTML as XML, or to load wild XML data: my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::HTMLParser' ) ; Aliases for the parser options: SMART|REGEXP => XML::Smart::Parser HTML => XML::Smart::HTMLParser So, you can use as: my $xml = new XML::Smart( 'some.xml' , 'smart' ) ; my $xml = new XML::Smart( 'some.xml' , 'html' ) ; =head1 Customizing the Parser. You can customize the way that the parser will treat the XML data: =head2 Forcing nodes/tags and arguments/attributes to lowercase or upercase: ## For lower case: my $xml = new XML::Smart( 'some.xml' , lowtag => 1 , lowarg => 1 , ) ; ## For uper case: my $xml = new XML::Smart( 'some.xml' , upertag => 1 , uperarg => 1 , ) ; =head2 Loading arguments without values (flags) as a TRUE boolean: I<** Note, this option will work only when the XML is parsed by XML::Smart::HTMLParser, since only it accept arguments without values!> my $xml = new XML::Smart( '' , 'XML::Smart::HTMLParser' , arg_single => 1 , ) ; Here's the tree of the example above: 'root' => { 'foo' => { 'flag' => 1, 'arg1' => '' }, }, =head2 Customizing the parse events: I can redirect the parsing process to personalized functions: my $xml = XML::Smart->new( 'some.xml' , on_start => \&on_start , on_char => \&on_char , on_end => \&on_end , ) ; sub on_start { my ( $tag , $pointer , $pointer_back ) = @_ ; $pointer->{$tag}{type_user} = 1 if $tag =~ /(?:name|age)/ ; } sub on_char { my ( $tag , $pointer , $pointer_back , $content) = @_ ; $$content =~ s/\s+/ /gs ; } sub on_end { my ( $tag , $pointer , $pointer_back ) = @_ ; $pointer->{$tag}{type_extra} = 1 if $tag =~ /(?:more|tel|address)/ ; } =head1 AUTHOR Graciliano M. P. I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P =head1 ePod This document was written in L (easy-POD), than converted to POD, and from here you know the way. =cut XML-Smart-1.78/lib/XML/Smart/Parser.pm0000644000175000017500000001316412110445245016604 0ustar harishharish############################################################################# ## Name: Parser.pm ## Purpose: XML::Smart::Parser ## Author: Paul Kulchenko (paulclinger@yahoo.com) ## Modified by: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 10/05/2003 ## RCS-ID: ## Copyright: 2000-2001 Paul Kulchenko ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ## ## This module is actualy XML::Parser::Lite (with some updates). It's here ## just for convenience. ## ## See original code at CPAN for full source and POD. ## ## This module will be used when XML::Parser is not installed. ############################################################################# # ====================================================================== # # Copyright (C) 2000-2001 Paul Kulchenko (paulclinger@yahoo.com) # SOAP::Lite is free software; you can redistribute it # and/or modify it under the same terms as Perl itself. # # $Id: Lite.pm,v 1.4 2001/10/15 21:25:05 paulk Exp $ # # Changes: Graciliano M. P. # # ====================================================================== package XML::Smart::Parser ; use 5.006 ; use strict ; use warnings ; use vars qw($VERSION) ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; $VERSION = 1.31 ; my(@parsed , @stack, $level) ; &compile(); sub new { _unset_sig_warn() ; my $class = ($_[0] =~ /^[\w:]+$/) ? shift(@_) : __PACKAGE__ ; my $this = bless {} , $class ; my %args = @_ ; _reset_sig_warn() ; $this->setHandlers(%args) ; $this->{NOENTITY} = 1 ; return $this ; } sub setHandlers { _unset_sig_warn() ; my $this = shift ; my %args = @_; _reset_sig_warn() ; $this->{Init} = $args{Init} || sub{} ; $this->{Start} = $args{Start} || sub{} ; $this->{Char} = $args{Char} || sub{} ; $this->{End} = $args{End} || sub{} ; $this->{Final} = $args{Final} || sub{} ; return 1 ; } sub regexp { my $patch = shift || '' ; my $package = __PACKAGE__ ; my $TextSE = "[^<]+"; my $UntilHyphen = "[^-]*-"; my $Until2Hyphens = "$UntilHyphen(?:[^-]$UntilHyphen)*-"; my $CommentCE = "$Until2Hyphens>?"; my $UntilRSBs = "[^\\]]*](?:[^\\]]+])*]+"; my $CDATA_CE = "$UntilRSBs(?:[^\\]>]$UntilRSBs)*>"; my $S = "[ \\n\\t\\r]+"; my $NameStrt = "[A-Za-z_:]|[^\\x00-\\x7F]"; my $NameChar = "[A-Za-z0-9_:.-]|[^\\x00-\\x7F]"; my $Name = "(?:$NameStrt)(?:$NameChar)*"; my $QuoteSE = "\"[^\"]*\"|'[^']*'"; my $DT_IdentSE = "$S$Name(?:$S(?:$Name|$QuoteSE))*"; my $MarkupDeclCE = "(?:[^\\]\"'><]+|$QuoteSE)*>"; my $S1 = "[\\n\\r\\t ]"; my $UntilQMs = "[^?]*\\?+"; my $PI_Tail = "\\?>|$S1$UntilQMs(?:[^>?]$UntilQMs)*>"; my $DT_ItemSE = "<(?:!(?:--$Until2Hyphens>|[^-]$MarkupDeclCE)|\\?$Name(?:$PI_Tail))|%$Name;|$S"; my $DocTypeCE = "$DT_IdentSE(?:$S)?(?:\\[(?:$DT_ItemSE)*](?:$S)?)?>?"; my $DeclCE = "--(?:$CommentCE)?|\\[CDATA\\[(?:($CDATA_CE)(?{${package}::char_CDATA(\$2)}))?|DOCTYPE(?:$DocTypeCE)?"; my $PI_CE = "$Name(?:$PI_Tail)?"; my $EndTagCE = "($Name)(?{${package}::end(\$3)})(?:$S)?>"; my $AttValSE = "\"([^<\"]*)\"|'([^<']*)'"; my $ElemTagCE = "($Name)(?:$S($Name)(?:$S)?=(?:$S)?(?:$AttValSE)(?{[\@{\$^R||[]},\$5=>defined\$6?\$6:\$7]}))*(?:$S)?(/)?>(?{${package}::start(\$4,\@{\$^R||[]})})(?{\${8} and ${package}::end(\$4)})"; my $MarkupSPE = "<(?:!(?:$DeclCE)?|\\?(?:$PI_CE)?|/(?:$EndTagCE)?|(?:$ElemTagCE)?)"; "(?:($TextSE)(?{${package}::char(\$1)}))$patch|$MarkupSPE"; } sub compile { local $^W; foreach (regexp(), regexp('??')) { eval qq{sub parse_re { use re "eval"; 1 while \$_[0] =~ m{$_}go }; 1} or die; last if eval { parse_re('bar'); 1 } }; _unset_sig_warn() ; *compile = sub {}; _reset_sig_warn() ; } sub parse { my $this = shift ; @parsed = () ; init(); parse_re($_[0]); final(); no strict qw(refs) ; my $final = pop(@parsed) ; pop(@parsed) ; for (my $i = 0 ; $i <= $#parsed ; $i+=2) { my $args = $parsed[$i+1] ; &{$this->{$parsed[$i]}}($this , (ref($args) ? @{$args} : $args) ) ; } @parsed = () ; return &{$this->{Final}}($this, @{$final}) ; } sub init { @stack = (); $level = 0; _unset_sig_warn() ; push(@parsed , 'Init' , [@_]) ; _reset_sig_warn() ; return ; } sub final { die "not properly closed tag '$stack[-1]'\n" if @stack; die "no element found\n" unless $level; _unset_sig_warn() ; push(@parsed , 'Final' , [@_]) ; _reset_sig_warn() ; return ; } sub start { die "multiple roots, wrong element '$_[0]'\n" if $level++ && !@stack; _unset_sig_warn() ; push(@stack, $_[0]); push(@parsed , 'Start' , [@_]) ; _reset_sig_warn() ; return ; } sub char { push(@parsed , 'Char' , [@_]) , return if @stack; for (my $i=0; $i < length $_[0]; $i++) { die "junk '$_[0]' @{[$level ? 'after' : 'before']} XML element\n" if index("\n\r\t ", substr($_[0],$i,1)) < 0; # or should '< $[' be there } return ; } sub char_CDATA { _unset_sig_warn() ; &char( substr($_[0] , 0 , -3) ) ; _reset_sig_warn() ; } sub end { pop(@stack) eq $_[0] or die "mismatched tag '$_[0]'\n"; push(@parsed , 'End' , [@_]) ; return ; } # ====================================================================== 1; XML-Smart-1.78/lib/XML/Smart/FAQ.pod0000644000175000017500000001173410155664446016143 0ustar harishharish =head1 NAME XML::Smart::FAQ - Frequently Asked Questions about XML::Smart. =head1 SYNOPSIS This is the Frequently Asked Questions list for XML::Smart. =head1 QUESTIONS B =head2 Do I need to install XML::Parser to can use XML::Smart? No! XML::Smart already comes with 2 independent parsers, XML::Smart::Parser and XML::Smart::HTMLParser. If L is found XML::Smart will use it by default, and the 2nd options will be XML::Smart::Parser. Note that for complex parsing L is recommended, but XML::Smart::Parser will work fine too. =head2 What is the best version of XML::Smart to install? Is always the last! Always take a look for new versions before aks for help on XML::Smart. Note that internally XML::Smart is complex, since the main idea of it is to remove the complexity from the hand of the programmer. Actually the idea is to enable the Perl programmer to use and create XML data without really know the XML format. =head2 Where can I learn about XML? http://www.xml.com =head2 How to apply a DTD to a XML::Smart object tree? Take a look in the method I. Example of use: $xml->apply_dtd(q` ]> `); This will format automatically elements, attributes, etc... =head2 How XML::Smart works? To create I, first I have created the module L. With it you can have an object that works at the same time as a HASH, ARRAY, SCALAR, CODE & GLOB. So you can do things like this with the same object: $obj = Object::MultiType->new() ; $obj->{key} ; $obj->[0] ; $obj->method ; @l = @{$obj} ; %h = %{$obj} ; &$obj(args) ; print $obj "send data\n" ; Seems to be crazy, and can be more if you use tie() inside it, and this is what I does. For I, the access in the Hash and Array way paste through tie(). In other words, you have a tied HASH and tied ARRAY inside it. This tied Hash and Array work together, soo B: %hash = ( key => ['a','b','c'] ) ; $hash->{key} ## return $hash{key}[0] $hash->{key}[0] ## return $hash{key}[0] $hash->{key}[1] ## return $hash{key}[1] ## Inverse: %hash = ( key => 'a' ) ; $hash->{key} ## return $hash{key} $hash->{key}[0] ## return $hash{key} $hash->{key}[1] ## return undef The best thing of this new resource is to avoid wrong access to the data and warnings when you try to access a Hash having an Array (and the inverse). Thing that generally make the script die(). Once having an easy access to the data, you can use the same resource to B data! For example: ## Previous data: ## Now you have {address} as a normal key with a string inside: $XML->{hosts}{server}{address} ## And to add a new address, the key {address} need to be an ARRAY ref! ## So, XML::Smart make the convertion: ;-P $XML->{hosts}{server}{address}[1] = '192.168.2.101' ; ## Adding to a list that you don't know the size: push(@{$XML->{hosts}{server}{address}} , '192.168.2.102') ; ## The data now:
192.168.2.100
192.168.2.101
192.168.2.102
Than after changing your XML tree using the Hash and Array resources you just get the data remade (through the Hash tree inside the object): my $xmldata = $XML->data ; B always return an object>! Even when you get a final key. So this actually returns another object, pointhing (inside it) to the key: $addr = $XML->{hosts}{server}{address}[0] ; ## Since $addr is an object you can TRY to access more data: $addr->{foo}{bar} ; ## This doens't make warnings! just return UNDEF. ## But you can use it like a normal SCALAR too: print "$addr\n" ; $addr .= ':80' ; ## After this $addr isn't an object any more, just a SCALAR! =head2 When I generate the XML data new lines (\n) are added to the content! You should use the options for the method data() and save() to not add identation to the generated data: $XML->data( noident => 1 ) ; ## or better: $XML->data( nospace => 1 ) ; =head2 Your question is not here? Just send me an e-mail. ;-P =head1 AUTHOR Graciliano M. P. I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P =head1 ePod This document was written in L (easy-POD), than converted to POD, and from here you know the way. =cut XML-Smart-1.78/lib/XML/Smart/XPath.pm0000644000175000017500000000433512101717070016372 0ustar harishharish############################################################################# ## Name: XPath.pm ## Purpose: XML::Smart::XPath - Compatibility with XPath (through XML::XPath). ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 01/10/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# ### MAINTAINER NOTE: Contains MEMLeak #### package XML::Smart::XPath ; use 5.006 ; use strict ; use warnings ; require Exporter ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION , @ISA) ; $VERSION = '0.05' ; @ISA = qw(Exporter) ; our @EXPORT = qw(xpath XPath xpath_pointer XPath_pointer) ; our @EXPORT_OK = @EXPORT ; my $load_XPath ; ############## # LOAD_XPATH # ############## sub load_XPath { return $load_XPath if $load_XPath ; eval(q`use XML::XPath ;`); if ($@) { warn("Error loading module XML::XPath! Can't use XPath with XML::Smart! Please install XML::XPath."); $load_XPath = undef ; } else { $load_XPath = 1 ; $XML::XPath::SafeMode = 1 ; } return $load_XPath ; } ######### # XPATH # ######### sub XPath { &xpath } ; sub xpath { my $this = shift ; load_XPath() ; my $xpath ; if ( $$this->{XPATH} ) { $xpath = ${$$this->{XPATH}} ;} if (!$xpath){ $xpath = XML::XPath->new( xml => $this->data(nospace => 1 , noheader => 1) ) ; $$this->{XPATH} = \$xpath ; } if ( !@_ ) { return $xpath ;} return ; } ################# # XPATH_POINTER # ################# sub XPath_pointer { &xpath_pointer } ; sub xpath_pointer { my $this = shift ; load_XPath() ; my $xpath = XML::XPath->new(xml => $this->data_pointer(nospace => 1 , noheader => 1)) ; if ( !@_ ) { return $xpath ;} return ; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart/Tutorial.epod0000644000175000017500000001207310053244256017467 0ustar harishharish=> NAME XML::Smart::Tutorial - Tutorial and examples for XML::Smart. => SYNOPSIS This document is a tutorial for I and shows some examples of usual things. => Working with contents: In I the key I is reserved and shouldn't be used directly, since I will deal with the convertion of arguments to node contents, including multiple node contents autimatically. ==> What happens when you set a value: $xml->{root}{foo} = 'simple value' ; Here foo will be a normal argument/attribute value, and will generate this XML data: But if you insert some tag or lines in the values by default I will convert it to a node content: $xml->{root}{foo} = "line0\nlien1\nline2\n" ; And will generate that XML data: line0 lien1 line2 But what you can do if you want to force some type, let's say, have a node content with a simple value: $xml->{root}{foo} = 'simple value' ; $xml->{root}{foo}->set_node(1) ; And will generate that XML data: simple value ==> Multiple contents: When you have interpolated content/data you need to work in a different. Let's say that you load this XML data: content0 content1 If you access directly the root key as string you will get all the content parts grouped. So, this code: my $xml = new XML::Smart(q` content0 content1 `,'smart') ; print "#$xml->{root}#" ; Will print that: # content0 content1 # B:> my @content = $xml->{root}->content ; print "#$content[0]#\n" ; And this will print that: # content0 # B with 2 arguments:> $xml->{root}->content(0,'new content') ; And now the XML data produced will be: new content content1 If you use the method I with only one argument it will remove all the multiple contents and will set the new value in the place of the 1st content. => Setting the XML Parser. By defaul I will use L or L (in this order of preference) to load a XML data. To force or define by your self the parser you can use the 2nd argument option when creating a I object: my $xml = new XML::Smart( 'some.xml' , 'XML::Parser' ) ; ## and my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::Parser' ) ; I also has an extra parser, I, that can be used to load HTML as XML, or to load wild XML data: my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::HTMLParser' ) ; Aliases for the parser options: SMART|REGEXP => XML::Smart::Parser HTML => XML::Smart::HTMLParser So, you can use as: my $xml = new XML::Smart( 'some.xml' , 'smart' ) ; my $xml = new XML::Smart( 'some.xml' , 'html' ) ; => Customizing the Parser. You can customize the way that the parser will treat the XML data: ==> Forcing nodes/tags and arguments/attributes to lowercase or upercase: ## For lower case: my $xml = new XML::Smart( 'some.xml' , lowtag => 1 , lowarg => 1 , ) ; ## For uper case: my $xml = new XML::Smart( 'some.xml' , upertag => 1 , uperarg => 1 , ) ; ==> Loading arguments without values (flags) as a TRUE boolean: I<** Note, this option will work only when the XML is parsed by XML::Smart::HTMLParser, since only it accept arguments without values!> my $xml = new XML::Smart( '' , 'XML::Smart::HTMLParser' , arg_single => 1 , ) ; Here's the tree of the example above: 'root' => { 'foo' => { 'flag' => 1, 'arg1' => '' }, }, ==> Customizing the parse events: I can redirect the parsing process to personalized functions: my $xml = XML::Smart->new( 'some.xml' , on_start => \&on_start , on_char => \&on_char , on_end => \&on_end , ) ; sub on_start { my ( $tag , $pointer , $pointer_back ) = @_ ; $pointer->{$tag}{type_user} = 1 if $tag =~ /(?:name|age)/ ; } sub on_char { my ( $tag , $pointer , $pointer_back , $content) = @_ ; $$content =~ s/\s+/ /gs ; } sub on_end { my ( $tag , $pointer , $pointer_back ) = @_ ; $pointer->{$tag}{type_extra} = 1 if $tag =~ /(?:more|tel|address)/ ; } => AUTHOR Graciliano M. P. I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P => ePod This document was written in L (easy-POD), than converted to POD, and from here you know the way. XML-Smart-1.78/lib/XML/Smart/Tie.pm0000644000175000017500000005011312103717717016074 0ustar harishharish############################################################################# ## Name: Tie.pm ## Purpose: XML::Smart::Tie - (XML::Smart::Tie::Array & XML::Smart::Tie::Hash) ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 28/09/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::Tie ; use 5.006 ; use strict ; use warnings ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; use vars qw($VERSION) ; $VERSION = 0.03 ; ###################### # _GENERATE_NULLTREE # ###################### sub _generate_nulltree { no warnings ; my $saver = shift ; my ( $K , $I ) = @_ ; $saver->{null} = 0 ; if ( !$saver->{keyprev} ) { return ;} my @tree = @{$saver->{keyprev}} ; if (!@tree) { return ;} if ( $I and $I > 0 ) { push(@tree , "[$I]") ;} my $tree = $saver->{tree} ; my ($keyprev , $iprev , $treeprev , $array , $key , $i) ; ##print "GEN>> @tree\n" ; foreach my $tree_i ( @tree ) { #print "*> $tree_i >> $keyprev # $iprev \n" ; #use Data::Dumper ; #print Dumper( [$tree , $treeprev , $array] ) ; #print "=====================\n" ; if (ref($tree) ne 'HASH' && ref($tree) ne 'ARRAY') { my $cont = $$treeprev{$keyprev} ; $$treeprev{$keyprev} = {} ; $$treeprev{$keyprev}{CONTENT} = $cont ; } if ($tree_i =~ /^\[(\d+)\]$/) { $i = $1 ; if (exists $$treeprev{$keyprev}) { if (ref $$treeprev{$keyprev} ne 'ARRAY') { my $prev = $$treeprev{$keyprev} ; $$treeprev{$keyprev} = [$prev] ; } } else { $$treeprev{$keyprev} = [] ;} if (!exists $$treeprev{$keyprev}[$i]) { $$treeprev{$keyprev}[$i] = {} ;} my $prev = $tree ; $tree = $$treeprev{$keyprev}[$i] ; $array = $$treeprev{$keyprev} ; $treeprev = $prev ; $iprev = $i ; } elsif (ref $tree eq 'ARRAY') { if (!exists $$tree[0] ) { $$tree[0] = {} ;} if ( ref($$tree[0]) eq 'HASH' && !exists $$tree[0]{$tree_i} ) { $$tree[0]{$tree_i} = {} ;} my $prev = $tree ; $tree = $$prev[0]{$tree_i} ; $array = undef ; $treeprev = $$prev[0] ; } else { if (exists $$tree{$tree_i}) { if (ref $$tree{$tree_i} ne 'HASH' && ref $$tree{$tree_i} ne 'ARRAY') { if ( $$tree{$tree_i} ne '' ) { my $cont = $$tree{$tree_i} ; $$tree{$tree_i} = {} ; $$tree{$tree_i}{CONTENT} = $cont ; } else { $$tree{$tree_i} = {} ;} } } else { if ( $treeprev ) { if ( $array ) { if ( ref($treeprev) eq 'ARRAY' ) { push( @{ $$treeprev[$iprev]{'/order'} } , keys_valids($$treeprev[$iprev]) ) if !$$treeprev[$iprev]{'/order'} || !@{ $$treeprev[$iprev]{'/order'} } ; push( @{ $$treeprev[$iprev]{'/order'} } , $tree_i) ; } else { push( @{ $$treeprev{'/order'} } , keys_valids($treeprev) ) if !$$treeprev{'/order'} || !@{ $$treeprev{'/order'} } ; push( @{ $$treeprev{'/order'} } , $tree_i ) ; } } else { if ( ref($treeprev) eq 'ARRAY' ) { push( @{ $$treeprev[$iprev]{$keyprev}{'/order'} } , keys_valids($$treeprev[$iprev]{$keyprev}) ) if !$$treeprev[$iprev]{$keyprev}{'/order'} || !@{ $$treeprev[$iprev]{$keyprev}{'/order'} } ; push( @{ $$treeprev[$iprev]{$keyprev}{'/order'} } , $tree_i) ; } else { push( @{ $$treeprev{$keyprev}{'/order'} } , keys_valids($$treeprev{$keyprev}) ) if !$$treeprev{$keyprev}{'/order'} || !@{ $$treeprev{$keyprev}{'/order'} } ; push( @{ $$treeprev{$keyprev}{'/order'} } , $tree_i ) ; } } } $$tree{$tree_i} = {} ; } $keyprev = $tree_i ; $iprev = undef ; $treeprev = $tree ; $tree = $$tree{$tree_i} ; $array = undef ; $key = $tree_i ; } } $saver->{point} = $tree ; $saver->{back} = $treeprev ; $saver->{array} = $array ; $saver->{key} = $key ; $saver->{i} = $i ; $saver->{null} = 0 ; ##use Data::Dumper ; print Dumper( $saver->{tree} , $saver->{point} , $saver->{back} , $saver->{array} ); return( 1 ) ; } sub keys_valids { my $tree = shift ; return () if ref $tree ne 'HASH' ; my @keys ; foreach my $Key (sort keys %$tree ) { if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;} push(@keys , $Key) ; } return @keys ; } ################# # _DELETE_XPATH # ################# sub _delete_XPATH { my $xpath = delete $_[0]->{XPATH} ; $$xpath = undef ; } ########################## # XML::SMART::TIE::ARRAY # ########################## package XML::Smart::Tie::Array ; sub TIEARRAY { my $class = shift ; my $saver = shift ; my $this = { saver => $saver } ; bless($this,$class) ; } sub FETCH { my $this = shift ; my ($i) = @_ ; my $key = $this->{saver}->{key} ; if ( $this->{saver}->{null} ) { &XML::Smart::Tie::_generate_nulltree($this->{saver},$key,$i) ; } my $point = '' ; #print "A-FETCH>> $key , $i >> @{$this->{saver}->{keyprev}} >> [$this->{saver}->{null}]\n" ; if ($this->{saver}->{array}) { if (!exists $this->{saver}->{array}[$i] ) { return &XML::Smart::clone($this->{saver},"/[$i]") ; } $point = $this->{saver}->{array}[$i] ; } elsif (exists $this->{saver}->{back}{$key}) { if (ref $this->{saver}->{back}{$key} eq 'ARRAY') { $point = $this->{saver}->{back}{$key}[$i] ; } else { if ($i == 0) { $point = $this->{saver}->{back}{$key} ;} else { return &XML::Smart::clone($this->{saver},"/[$i]") ;} } } else { return &XML::Smart::clone($this->{saver},"/[$i]") ; } if (ref $point) { return &XML::Smart::clone($this->{saver},$point,undef,undef,undef,$i) ; } else { return &XML::Smart::clone($this->{saver}, {},undef,undef,undef,$i,$point) ; } } sub STORE { my $this = shift ; my $i = shift ; my $key = $this->{saver}->{key} ; #print "A-STORE>> $key , $i >> @{$this->{saver}->{keyprev}} >> [$this->{saver}->{array}]\n" ; if ( $this->{saver}->{null} ) { &XML::Smart::Tie::_generate_nulltree($this->{saver},$key,$i) ; } &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ($this->{saver}->{array}) { if ( !exists $this->{saver}->{array}[$i] && $key !~ /^\/\.CONTENT/ ) { push( @{$this->{saver}->{back}->{'/order'}} , $key ) ; } return $this->{saver}->{array}[$i] = $_[0] ; } elsif ($i == 0) { if (ref $this->{saver}->{back}{$key} eq 'ARRAY') { return $this->{saver}->{back}{$key}[0] = $_[0] ; } else { return $this->{saver}->{back}{$key} = $_[0] ; } } else { if ( exists $this->{saver}->{back}{$key}) { my $k = $this->{saver}->{back}{$key} ; $this->{saver}->{back}{$key} = [$k] ; } else { $this->{saver}->{back}{$key} = [] ;} $this->{saver}->{array} = $this->{saver}->{back}{$key} ; if ( !exists $this->{saver}->{array}[$i] && $key !~ /^\/\.CONTENT/ ) { if ( !exists $this->{saver}->{back}->{'/order'} ) { my %keys = map { ( $_ eq '/order' || $_ eq '/nodes' ? () : ($_ => 1) ) } keys %{$this->{saver}->{back}} ; push( @{$this->{saver}->{back}->{'/order'}} , sort keys %keys ) ; } push( @{$this->{saver}->{back}->{'/order'}} , $key ) ; } return $this->{saver}->{array}[$i] = $_[0] ; } return ; } sub FETCHSIZE { no warnings ; my $this = shift ; my $i = shift ; my $key = $this->{saver}->{key} ; my @call = caller ; if ($this->{saver}->{array}) { return( $#{$this->{saver}->{array}} + 1 ) ; } elsif ($i == 0 && exists $this->{saver}->{back}{$key}) { return 1 ;} ## Always return 1! Then when the FETCH(0) is made, it returns a NULL object. ## This will avoid warnings! return 1 ; } sub EXISTS { my $this = shift ; my $i = shift ; my $key = $this->{saver}->{key} ; if ($this->{saver}->{array}) { if (exists $this->{saver}->{array}[$i]) { return 1 ;} } elsif ($i == 0 && exists $this->{saver}->{back}{$key}) { return 1 ;} return ; } sub DELETE { my $this = shift ; my $i = shift ; my $key = $this->{saver}->{key} ; &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ($this->{saver}->{array}) { if (exists $this->{saver}->{array}[$i]) { return delete $this->{saver}->{array}[$i] ; } } elsif ($i == 0 && exists $this->{saver}->{back}{$key}) { my $k = $this->{saver}->{back}{$key} ; delete $this->{saver}->{back}{'/nodes'}{$k} if defined $this->{saver}->{back}{'/nodes'} ; delete $this->{saver}->{back}{$key} ; return $k ; } return ; } sub CLEAR { my $this = shift ; my $key = $this->{saver}->{key} ; &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ($this->{saver}->{array}) { return @{$this->{saver}->{array}} = () ; } elsif (exists $this->{saver}->{back}{$key}) { return $this->{saver}->{back}{$key} = () ; } return ; } sub PUSH { my $this = shift ; my $key = $this->{saver}->{key} ; ##print "PUSH>> $key >> @{$this->{saver}->{keyprev}}\n" ; my $gen_null ; if ( $this->{saver}->{null} ) { $gen_null = &XML::Smart::Tie::_generate_nulltree($this->{saver},$key) ; } &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ( !$this->{saver}->{array} ) { if (exists $this->{saver}->{back}{$key}) { if ( ref $this->{saver}->{back}{$key} ne 'ARRAY' ) { my $k = $this->{saver}->{back}{$key} ; $this->{saver}->{back}{$key} = [ ( $gen_null ? () : $k) ] ; } } else { $this->{saver}->{back}{$key} = [] ;} $this->{saver}->{array} = $this->{saver}->{back}{$key} ; $this->{saver}->{point} = $this->{saver}->{back}{$key}[0] ; } return push(@{$this->{saver}->{array}} , @_) ; } sub UNSHIFT { my $this = shift ; my $key = $this->{saver}->{key} ; my $gen_null ; if ( $this->{saver}->{null} ) { $gen_null = &XML::Smart::Tie::_generate_nulltree($this->{saver},$key) ; } &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ( !$this->{saver}->{array} ) { if (exists $this->{saver}->{back}{$key}) { if ( ref $this->{saver}->{back}{$key} ne 'ARRAY' ) { my $k = $this->{saver}->{back}{$key} ; $this->{saver}->{back}{$key} = [ ( $gen_null ? () : $k) ] ; } } else { $this->{saver}->{back}{$key} = [] ;} $this->{saver}->{array} = $this->{saver}->{back}{$key} ; $this->{saver}->{point} = $this->{saver}->{back}{$key}[0] ; } return unshift(@{$this->{saver}->{array}} , @_ ) ; } sub SPLICE { my $this = shift ; my $offset = shift || 0 ; my $length = shift || $this->FETCHSIZE() - $offset ; my $key = $this->{saver}->{key} ; if ( $this->{saver}->{null} ) { &XML::Smart::Tie::_generate_nulltree($this->{saver},$key) ; } &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; if ( !$this->{saver}->{array} ) { if (exists $this->{saver}->{back}{$key}) { if ( ref $this->{saver}->{back}{$key} ne 'ARRAY' ) { my $k = $this->{saver}->{back}{$key} ; $this->{saver}->{back}{$key} = [$k] ; } } else { $this->{saver}->{back}{$key} = [] ;} $this->{saver}->{array} = $this->{saver}->{back}{$key} ; $this->{saver}->{point} = $this->{saver}->{back}{$key}[0] ; } return splice(@{$this->{saver}->{array}} , $offset , $length , @_) ; } sub POP { my $this = shift ; my $key = $this->{saver}->{key} ; &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; my $pop ; if (!$this->{saver}->{array} && exists $this->{saver}->{back}{$key}) { if ( ref $this->{saver}->{back}{$key} eq 'ARRAY' ) { $this->{saver}->{array} = $this->{saver}->{back}{$key} ; $this->{saver}->{point} = $this->{saver}->{back}{$key}[0] ; } else { $pop = delete $this->{saver}->{back}{$key} ;} } if ($this->{saver}->{array}) { $pop = pop( @{$this->{saver}->{array}} ) ; if ( $#{$this->{saver}->{array}} == 0 ) { $this->{saver}->{back}{$key} = $this->{saver}->{array}[0] ; $this->{saver}->{array} = undef ; $this->{saver}->{i} = undef ; } elsif ( $#{$this->{saver}->{array}} < 0 ) { $this->{saver}->{back}{$key} = undef ; $this->{saver}->{array} = undef ; $this->{saver}->{i} = undef ; } } return $pop ; } sub SHIFT { my $this = shift ; my $key = $this->{saver}->{key} ; &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; my $shift ; if (!$this->{saver}->{array} && exists $this->{saver}->{back}{$key}) { if ( ref $this->{saver}->{back}{$key} eq 'ARRAY' ) { $this->{saver}->{array} = $this->{saver}->{back}{$key} ; $this->{saver}->{point} = $this->{saver}->{back}{$key}[0] ; } else { $shift = delete $this->{saver}->{back}{$key} ;} } if ($this->{saver}->{array}) { $shift = shift( @{$this->{saver}->{array}} ) ; if ( $#{$this->{saver}->{array}} == 0 ) { $this->{saver}->{back}{$key} = $this->{saver}->{array}[0] ; $this->{saver}->{array} = undef ; $this->{saver}->{i} = undef ; } elsif ( $#{$this->{saver}->{array}} < 0 ) { $this->{saver}->{back}{$key} = undef ; $this->{saver}->{array} = undef ; $this->{saver}->{i} = undef ; } } return $shift ; } sub STORESIZE {} sub EXTEND {} sub UNTIE {} sub DESTROY {} ######################### # XML::SMART::TIE::HASH # ######################### package XML::Smart::Tie::Hash ; sub TIEHASH { my $class = shift ; my $saver = shift ; my $this = { saver => $saver } ; bless($this,$class) ; } sub FETCH { my $this = shift ; my ( $key ) = @_ ; my $i ; if ( $this->{saver}->{null} ) { &XML::Smart::Tie::_generate_nulltree($this->{saver},$key,$i) ; } #print "H-FETCH>> $key >> ". ( $this->{saver}->{keyprev} ? "@{$this->{saver}->{keyprev}}" : '' ) ."\n" ; #print "**FETCH>> $this->{saver}->{point}\n" ; my $point = '' ; my $array ; if (0&&ref($this->{saver}->{point}) eq 'ARRAY') { $array = $this->{saver}->{point} ; $point = $this->{saver}->{point}[0] ; my $xml = &XML::Smart::clone($this->{saver},$point,undef,$array, undef,0) ; return $xml->{$key} ; } elsif (ref($this->{saver}->{point}{$key}) eq 'ARRAY') { $array = $this->{saver}->{point}{$key} ; $point = $this->{saver}->{point}{$key}[0] ; $i = 0 ; } elsif ( exists $this->{saver}->{point}{$key} ) { $point = $this->{saver}->{point}{$key} ; } else { return &XML::Smart::clone($this->{saver},$key) ; } if (ref $point) { return &XML::Smart::clone($this->{saver},$point,undef,$array,$key,$i) ; } else { return &XML::Smart::clone($this->{saver},{} ,undef,$array,$key,$i,$point) ; } } sub FIRSTKEY { my $this = shift ; if (!$this->{saver}->{keyorder}) { $this->_keyorder ;} return( @{$this->{saver}->{keyorder}}[0] ) ; } sub NEXTKEY { my $this = shift ; my ( $key ) = @_ ; if (!$this->{saver}->{keyorder}) { $this->_keyorder ;} my $found ; foreach my $key_i ( @{$this->{saver}->{keyorder}} ) { if ($found) { return($key_i) ;} if ($key eq $key_i) { $found = 1 ;} } return ; } sub STORE { my $this = shift ; my $key = shift ; ##print "H-STORE>> $key >> @{$this->{saver}->{keyprev}} >> [$this->{saver}->{null}]\n" ; if ( $this->{saver}->{null} ) { &XML::Smart::Tie::_generate_nulltree($this->{saver},$key) ; } &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; ##my @call = caller ; ##print "***STORE>> $this->{saver}->{point} [@call] $_[0]\n" ; if (ref($this->{saver}->{point}) eq 'ARRAY') { return $this->{saver}->{point}[0]{$key} = $_[0] ; } elsif ( ref($this->{saver}->{point}{$key}) eq 'ARRAY' ) { return $this->{saver}->{point}{$key}[0] = $_[0] ; } else { if ( defined $this->{saver}->{content} && ( keys %{$this->{saver}->{point}} ) < 1 ) { my $prev_key = $this->{saver}->{key} ; $this->{saver}->{back}{$prev_key} = {} ; $this->{saver}->{back}{$prev_key}{CONTENT} = ${$this->{saver}->{content}} ; delete $this->{saver}->{content} ; $this->{saver}->{point} = $this->{saver}->{back}{$prev_key} ; } if ( !exists $this->{saver}->{point}{$key} ) { if ($key ne '/order' && $key ne '/nodes') { if (!$this->{saver}->{keyorder}) { $this->_keyorder ;} push(@{$this->{saver}->{keyorder}} , $key) ; push(@{$this->{saver}->{point}{'/order'}} , $key ) ; } } return $this->{saver}->{point}{$key} = $_[0] ; } return ; } sub DELETE { my $this = shift ; my ( $key ) = @_ ; if ( exists $this->{saver}->{point}{$key} ) { &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; $this->{saver}->{keyorder} = undef ; if ( defined $this->{saver}->{point}{'/order'} ) { my (@order_ok , $set) ; foreach my $order_i ( @{ $this->{saver}->{point}{'/order'} } ) { if ($order_i eq $key) { $set = 1 ;} else { push(@order_ok , $order_i) ;} } @{ $this->{saver}->{point}{'/order'} } = @order_ok if $set ; } delete $this->{saver}->{point}{'/nodes'}{$key} if defined $this->{saver}->{point}{'/nodes'}{$key} ; return delete $this->{saver}->{point}{$key} ; } return ; } sub CLEAR { my $this = shift ; &XML::Smart::Tie::_delete_XPATH($this->{saver}) ; $this->{saver}->{keyorder} = undef ; %{$this->{saver}->{point}} = () ; } sub EXISTS { my $this = shift ; my ( $key ) = @_ ; if ( exists $this->{saver}->{point}{$key} ) { return( 1 ) ;} return ; } sub UNTIE {} sub DESTROY {} sub _keyorder { my $this = shift ; my @order ; if ( $this->{saver}->{point}{'/order'} ) { my %keys ; foreach my $keys_i ( @{ $this->{saver}->{point}{'/order'} } , sort keys %{ $this->{saver}->{point} } ) { if ($keys_i eq '' || $keys_i eq '/order' || $keys_i eq '/nodes') { next ;} if ( !$keys{$keys_i} ) { push(@order , $keys_i) ; $keys{$keys_i} = 1 ; } } } else { foreach my $Key ( sort keys %{ $this->{saver}->{point} } ) { if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;} push(@order , $Key) ; } } $this->{saver}->{keyorder} = \@order ; } ######################### # XML::SMART::TIESCALAR # ######################### package XML::Smart::TieScalar ; sub TIESCALAR { my $class = shift ; my $this = bless( { p => $_[0] } , __PACKAGE__ ) ; return $this ; } sub FETCH { my $this = shift ; my $wantarray = shift ; my ($data , @data) ; foreach my $k_i ( $this->_get_content_keys ) { if ( $wantarray ) { push(@data , $this->{p}{$k_i}) ;} else { $data .= $this->{p}{$k_i} ;} } return @data if $wantarray ; return $data ; } sub STORE { my $this = shift ; my $i = $#_ > 0 ? shift : undef ; if ( $i =~ /^\d+$/ ) { my $set ; foreach my $k_i ( $this->_get_content_keys ) { if ( $k_i =~ /^\/\.CONTENT\/$i$/ ) { $this->{p}{$k_i} = $_[0] ; $set = 1 ; last ; } } if ( !$set ) { $this->{p}{"/.CONTENT/$i"} = $_[0] ; push( @{$this->{p}{'/order'}} , "/.CONTENT/$i") ; $this->_cache_keys ; } return $this->{p}{CONTENT} ; } untie $this->{p}{CONTENT} ; foreach my $k_i ( $this->_get_content_keys ) { delete $this->{p}{$k_i} ; } if ( $this->{p}{'/order'} ) { my @order = @{$this->{p}{'/order'}} ; my @order_ok ; foreach my $order_i ( @order ) { push(@order_ok , $order_i) if $order_i !~ /^\/\.CONTENT\/\d+$/ ;} if (@order_ok) { $this->{p}{'/order'} = \@order_ok ;} else { delete $this->{p}{'/order'} ;} } $this->{p}{CONTENT} = $_[0] ; } sub UNTIE {} sub DESTROY {} sub _cache_keys { my $this = shift ; delete $this->{K} ; my @keys = $this->_get_content_keys ; $this->{K} = \@keys ; } sub _get_content_keys { my $this = shift ; return @{$this->{K}} if $this->{K} ; my %keys ; foreach my $Key ( keys %{ $this->{p} } ) { if ( $Key =~ /^\/\.CONTENT\/(\d+)$/ ) { $keys{$1} = $Key ;} } my @keys = map { $keys{$_} } sort { $a <=> $b } keys %keys ; return @keys ; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart/Base64.pm0000644000175000017500000001402412101754765016402 0ustar harishharish############################################################################# ## Name: Base64.pm ## Purpose: XML::Smart::Base64 ## Author: Graciliano M. P. ## Modified by: ## Created: 25/5/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# ## ## Modified by Harish to fix bugs in xml creation and to errors more readable. ## Tue Nov 1 21:18:43 IST 2011 ############################################################################ package XML::Smart::Base64 ; use strict ; use warnings ; use Carp ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our $VERSION = '1.3' ; my ($BASE64_PM) ; eval("use MIME::Base64 ()") ; if ( defined &MIME::Base64::encode_base64 ) { $BASE64_PM = 1 ;} ################# # ENCODE_BASE64 # ################# sub encode_base64 { my $value = $_[0] ; if( $BASE64_PM ) { eval { _unset_sig_warn() ; my $encoded = MIME::Base64::encode_base64( $value ) ; my $decoded = MIME::Base64::decode_base64( $encoded) ; _reset_sig_warn() ; my $tmp_decoded = $decoded ; $tmp_decoded =~ s/\n//g ; my $tmp_value = $value ; $tmp_value =~ s/\n//g ; return $encoded if( $tmp_decoded eq $tmp_value ) ; }; } { my $encoded ; my $decoded ; my $tmp_value ; my $tmp_decoded ; eval { _unset_sig_warn() ; $encoded = _encode_base64_pure_perl( $value ) ; $decoded = _decode_base64_pure_perl( $encoded ) ; _reset_sig_warn() ; $tmp_decoded = $decoded ; $tmp_decoded =~ s/\n//g ; $tmp_value = $value ; $tmp_value =~ s/\n//g ; } ; unless( $@ ) { return $encoded if( $tmp_decoded eq $tmp_value ) ; } } { _unset_sig_warn() ; my $encoded = _encode_ord_special( $value ) ; my $decoded = _decode_ord_special( $encoded ) ; _reset_sig_warn() ; my $tmp_decoded = $decoded ; $tmp_decoded =~ s/\n//g ; my $tmp_value = $value ; $tmp_value =~ s/\n//g ; return $encoded if( $tmp_decoded eq $tmp_value ) ; } croak( "Error Encoding\n" ) ; } ############################ # _ENCODE_BASE64_PURE_PERL # ############################ sub _encode_base64_pure_perl { my $res = ""; my $eol = $_[1]; $eol = "\n" unless defined $eol; pos($_[0]) = 0; # ensure start at the beginning while ($_[0] =~ /(.{1,45})/gs) { my $text = $1 ; $res .= substr( pack('u', $text ), 1 ) ; chop($res); } $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs # fix padding at the end my $padding = (3 - length($_[0]) % 3) % 3; $res =~ s/.{$padding}$/'=' x $padding/e if $padding; # break encoded string into lines of no more than 76 characters each if (length $eol) { $res =~ s/(.{1,76})/$1$eol/g; } $res; } ############################ # _ENCODE_ORD_SPECIAL # ############################ sub _encode_ord_special { my $value = shift ; my @chars = split( //, $value ) ; my @ords ; foreach my $char ( @chars ) { push @ords, ord( $char ) ; } return join( "|", @ords ) ; } ############################ # _DECODE_ORD_SPECIAL # ############################ sub _decode_ord_special { my $value = shift ; my @ords = split( /\|/, $value ) ; my @chars ; foreach my $ord ( @ords ) { push @chars, chr( $ord ) ; } return join( "", @chars ) ; } ################# # DECODE_BASE64 # ################# sub decode_base64 { my $value = $_[0] ; if( $BASE64_PM ) { eval { _unset_sig_warn() ; my $decoded = MIME::Base64::decode_base64( $value ) ; my $encoded = MIME::Base64::encode_base64( $decoded ) ; _reset_sig_warn() ; my $tmp_value = $value ; $tmp_value =~ s/\n//g ; my $tmp_encoded = $encoded ; $tmp_encoded =~ s/\n//g ; return $decoded if( $tmp_encoded eq $tmp_value ) ; }; } { my $decoded ; my $encoded ; my $tmp_value ; my $tmp_encoded ; eval { $decoded = _decode_base64_pure_perl( $value ) ; $encoded = _encode_base64_pure_perl( $decoded ) ; $tmp_value = $value ; $tmp_value =~ s/\n//g ; $tmp_encoded = $encoded ; $tmp_encoded =~ s/\n//g ; } ; unless( $@ ) { return $decoded if( $tmp_encoded eq $tmp_value ) ; } } { my $decoded = _decode_ord_special( $value ) ; my $encoded = _encode_ord_special( $decoded ) ; my $tmp_value = $value ; $tmp_value =~ s/\n//g ; my $tmp_encoded = $encoded ; $tmp_encoded =~ s/\n//g ; return $decoded if( $tmp_encoded eq $tmp_value ) ; } croak "Error Decoding $value\n" ; } ############################ # _DECODE_BASE64_PURE_PERL # ############################ sub _decode_base64_pure_perl { local($^W) = 0 ; my $str = shift ; my $res = ""; $str =~ tr|A-Za-z0-9+=/||cd; # remove non-base64 chars if (length($str) % 4) { #require Carp; #Carp::carp("Length of base64 data not a multiple of 4") } $str =~ s/=+$//; # remove padding $str =~ tr|A-Za-z0-9+/| -_|; # convert to uuencoded format while ($str =~ /(.{1,60})/gs) { my $len = chr(32 + length($1)*3/4); # compute length byte $res .= unpack("u", $len . $1 ); # uudecode } $res; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart/DTD.pm0000644000175000017500000006402712101755405015771 0ustar harishharish############################################################################# ## Name: DTD.pm ## Purpose: XML::Smart::DTD - Apply DTD over a XML::Smart object. ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 25/05/2004 ## RCS-ID: ## ## The DTD parser was based on XML-DTDParser-1.7 ## by Jenda@Krynicky.cz http://Jenda.Krynicky.cz ## ## Copyright: (c) 2004 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::DTD ; use strict ; use warnings ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION , @ISA) ; $VERSION = '0.05' ; ######## # VARS # ######## my $RE_quoted = qr/(?:"[^"\\]?"|"(?:(?:\\")|[^"])+(?!\\)[^"]?"|'[^'\\]?'|'(?:(?:\\')|[^'])+(?!\\)[^']')/s ; my $namechar = qr/[#\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF0-9\xB7._:-]/; my $name = qr/[\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF_:]$namechar*/ ; my $nameX = qr/$name[.?+*]*/ ; my $nmtoken = qr/$namechar+/ ; my $AttType = qr/(?:CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|\(.*?\)|NOTATION ?\(.*?\))/ ; my $DefaultDecl = qr/(?:#REQUIRED|#IMPLIED|#FIXED)/ ; my $AttDef = qr/($name)[ \t]+($AttType)(?:[ \t]+($DefaultDecl))?(?:[ \t]+($RE_quoted))?/ ; #{ # my (@sub) = ( join ("", ) =~ /\n\s*sub\s+(\w+)/gs ); # foreach my $sub_i (sort @sub ) { print "=>head2 $sub_i\n" ;} #} #__DATA__ ############### # AUTOLOADERS # ############### sub get_url { require XML::Smart::Tree ; *get_url = \*XML::Smart::Tree::get_url ; &XML::Smart::Tree::get_url(@_) ; } ####### # NEW # ####### sub new { my $class = shift ; my $dtd = shift ; $dtd =~ s/^file:\/\/\/?// ; my $this = bless({} , $class) ; $this->{tree} = $this->ParseDTD($dtd) ; return $this ; } ################################################################################ ############### # ELEM_EXISTS # ############### sub elem_exists { my $this = shift ; my ( $tag ) = @_ ; return 1 if $this->{tree}{$tag} ; return undef ; } ################ # CHILD_EXISTS # ################ sub child_exists { my $this = shift ; my ( $tag , $child ) = @_ ; return undef if !$this->{tree}{$tag} || !$this->{tree}{$tag}{children} ; return 1 if $this->{tree}{$tag}{children}{$child} ; return undef ; } ################ # IS_ELEM_UNIQ # ################ sub is_elem_uniq { my $this = shift ; return ( $this->get_elem_opt(@_) =~ /^[\!]?$/ ) ? 1 : undef ; } ###################### # IS_ELEM_CHILD_UNIQ # ###################### sub is_elem_child_uniq { my $this = shift ; return ( $this->get_elem_child_opt(@_) =~ /^[\!]?$/ ) ? 1 : undef ; } ################# # IS_ELEM_MULTI # ################# sub is_elem_multi { my $this = shift ; return ( $this->get_elem_opt(@_) =~ /^[\+\*]$/ ) ? 1 : undef ; } ####################### # IS_ELEM_CHILD_MULTI # ####################### sub is_elem_child_multi { my $this = shift ; return ( $this->get_elem_child_opt(@_) =~ /^[\+\*]$/ ) ? 1 : undef ; } ############### # IS_ELEM_REQ # ############### sub is_elem_req { my $this = shift ; return ( $this->get_elem_opt(@_) =~ /^[\!\+]?$/ ) ? 1 : undef ; } ##################### # IS_ELEM_CHILD_REQ # ##################### sub is_elem_child_req { my $this = shift ; return ( $this->get_elem_child_opt(@_) =~ /^[\!\+]?$/ ) ? 1 : undef ; } ############### # IS_ELEM_OPT # ############### sub is_elem_opt { my $this = shift ; return ( $this->get_elem_opt(@_) =~ /^[\?\*]$/ ) ? 1 : undef ; } ##################### # IS_ELEM_CHILD_OPT # ##################### sub is_elem_child_opt { my $this = shift ; return ( $this->get_elem_child_opt(@_) =~ /^[\?\*]$/ ) ? 1 : undef ; } ################ # GET_ELEM_OPT # ################ sub get_elem_opt { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} ; return $this->{tree}{$tag}{option} ; } ###################### # GET_ELEM_CHILD_OPT # ###################### sub get_elem_child_opt { my $this = shift ; my ( $tag , $child ) = @_ ; return undef if !$this->{tree}{$tag} || !$this->{tree}{$tag}{children} ; return $this->{tree}{$tag}{children}{$child} ; } ############### # IS_ELEM_ANY # ############### sub is_elem_any { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} ; return 1 if $this->{tree}{$tag}{any} ; return undef ; } ################## # IS_ELEM_PCDATA # ################## sub is_elem_pcdata { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} ; return 1 if $this->{tree}{$tag}{content} ; } ################# # IS_ELEM_EMPTY # ################# sub is_elem_empty { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} ; return 1 if $this->{tree}{$tag}{empty} ; return undef ; } ################## # IS_ELEM_PARENT # ################## sub is_elem_parent { my $this = shift ; my ( $tag , @chk_parent ) = @_ ; return undef if !$this->{tree}{$tag} ; my @parents = ref($this->{tree}{$tag}{parent}) eq 'ARRAY' ? @{$this->{tree}{$tag}{parent}} : () ; my %parents = map { $_ => 1 } @parents ; foreach my $chk_parent_i ( @chk_parent ) { next if $chk_parent_i eq '' ; return undef if !$parents{$chk_parent_i} ; } return 1 ; } ############### # ATTR_EXISTS # ############### sub attr_exists { my $this = shift ; my ( $tag , @attrs ) = @_ ; return undef if !$this->{tree}{$tag} ; foreach my $attrs_i ( @attrs ) { return undef if !$this->{tree}{$tag}{attributes}{$attrs_i} ; } return 1 ; } ############### # IS_ATTR_REQ # ############### sub is_attr_req { my $this = shift ; my ( $tag , $attr ) = @_ ; _unset_sig_warn() ; my $attr_check = $this->{tree}{$tag}{attributes}{$attr} ; _reset_sig_warn() ; return undef if( !$this->{tree}{$tag} || !$attr_check ) ; my $opt = @{$this->{tree}{$tag}{attributes}{$attr}}[1] ; return 1 if( $opt && ($opt =~ /#REQUIRED/i ) ) ; return undef ; } ############### # IS_ATTR_FIX # ############### sub is_attr_fix { my $this = shift ; my ( $tag , $attr ) = @_ ; return undef if !$this->{tree}{$tag} || !$this->{tree}{$tag}{attributes}{$attr} ; my $opt = @{$this->{tree}{$tag}{attributes}{$attr}}[1] ; return 1 if $opt =~ /#FIXED/i ; return undef ; } ################# # GET_ATTR_TYPE # ################# sub get_attr_type { my $this = shift ; my ( $tag , $attr ) = @_ ; return undef if !$this->{tree}{$tag} || !$this->{tree}{$tag}{attributes}{$attr} ; my $type = @{$this->{tree}{$tag}{attributes}{$attr}}[0] ; return $type ; } ################ # GET_ATTR_DEF # ################ sub get_attr_def { my $this = shift ; my ( $tag , $attr ) = @_ ; return () if !$this->{tree}{$tag} || !$this->{tree}{$tag}{attributes}{$attr} ; my $def = @{$this->{tree}{$tag}{attributes}{$attr}}[2] ; return $def ; } ################### # GET_ATTR_VALUES # ################### sub get_attr_values { my $this = shift ; my ( $tag , $attr ) = @_ ; return () if !$this->{tree}{$tag} || !$this->{tree}{$tag}{attributes}{$attr} ; my $vals = @{$this->{tree}{$tag}{attributes}{$attr}}[3] ; return @$vals if ref $vals eq 'ARRAY' ; return () ; } ############## # GET_CHILDS # ############## sub get_childs { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} ; return @{$this->{tree}{$tag}{childrenARR}} if $this->{tree}{$tag}{childrenARR} && @{$this->{tree}{$tag}{childrenARR}} ; return () ; } ################## # GET_CHILDS_REQ # ################## sub get_childs_req { my $this = shift ; my ( $tag ) = @_ ; my @childs = $this->get_childs($tag) ; my @childs_req ; foreach my $child_i ( @childs ) { push(@childs_req , $child_i) if $this->is_elem_child_req($tag , $child_i) ; } return @childs_req ; } ############# # GET_ATTRS # ############# sub get_attrs { my $this = shift ; my ( $tag ) = @_ ; return undef if !$this->{tree}{$tag} || !$this->{tree}{$tag}{attr_order} ; my @attrs = @{$this->{tree}{$tag}{attr_order}} ; return @attrs ; } ################# # GET_ATTRS_REQ # ################# sub get_attrs_req { my $this = shift ; my ( $tag ) = @_ ; my @attrs = $this->get_attrs($tag) ; my @attr_req ; foreach my $attrs_i ( @attrs ) { push(@attr_req , $attrs_i) if $this->is_attr_req($tag , $attrs_i) ; } return @attr_req ; } ######### # ERROR # ######### sub error { my $this = shift ; if ( @_ ) { push( @{$this->{ERRORS}} , @_) ;} return @{ $this->{ERRORS} } if $this->{ERRORS} && @{$this->{ERRORS}} ; return () ; } ######## # TREE # ######## sub tree { return $_[0]->{tree} ; } ######## # ROOT # ######## sub root { return $_[0]->{root} ; } ############ # PARSEDTD # ############ sub ParseDTD { my $this = shift ; my $xml = read_data( shift(@_) ) ; $this->{DATA} = $xml ; my (%elements, %definitions) ; $xml =~ s/\s+/ /gs ; while ($xml =~ s{}{}io) { my ($percent, $entity, $include) = ($1,$2,$3) ; $percent = '&' unless $percent; my $definition = read_data($include) ; $definition =~ s/\s+/ /gs ; $xml =~ s{\Q$percent$entity;\E}{$definition}g ; } $xml =~ s{}{}gs ; $xml =~ s{<\?.*?\?>}{}gs ; while ($xml =~ s{}{}io) { my ($percent, $entity, $definition) = ($1,$2,$3) ; $percent = '&' unless $percent ; $definitions{"$percent$entity"} = $definition ; } { my $replacements = 0 ; 1 while ++$replacements < 1000 and $xml =~ s{([&%]$name);}{(exists $definitions{$1} ? $definitions{$1} : "$1\x01;")}ge; $this->error("Recursive or too many entities!") if $xml =~ m{([&%]$name);} ; } undef %definitions ; $xml =~ tr/\x01//d ; while ($xml =~ s{}{}io) { my ($element, $children, $option) = ($1,$2,$3); $elements{$element}->{childrenSTR} = $children . $option ; $children =~ s/\s//g ; if ($children eq '(#PCDATA)') { $children = '#PCDATA' ;} elsif ( $children =~ s/^\((#PCDATA(?:\|$name)+)\)$/$1/o && $option eq '*') { $children =~ s/\|/*,/g ; $children .= '*' ; } else { $children = simplify_children( $children, $option) ;} $this->error(" is not valid!") unless $children =~ m{^#?$nameX(?:,$nameX)*$} ; $elements{$element}->{childrenARR} = [] ; foreach my $child (split ',', $children) { $child =~ s/([\?\*\+])$// and $option = $1 or $option = '!' ; $elements{$element}->{children}->{$child} = $option ; push @{$elements{$element}->{childrenARR}}, $child unless $child eq '#PCDATA' ; } delete $elements{$element}->{childrenARR} if !@{$elements{$element}->{childrenARR}} ; } while ($xml =~ s{}{}io) { my ($element, $param) = ($1,$2) ; if ( uc($param) eq 'ANY') { $elements{$element}->{any} = 1 ;} elsif ( uc($param) eq 'EMPTY') { $elements{$element}->{empty} = 1 ;} } while ($xml =~ s{}{}io) { my ($element, $attributes) = ($1,$2); $this->error(" referenced by an not found!") unless exists $elements{$element} ; while ($attributes =~ s/^\s*$AttDef//io) { my ($name,$type,$option,$default) = ($1,$2,$3,$4); if ( $default && ( $default =~ /^"(.*?)"$/ ) ) { $default = $1 ; $default =~ s/\\"/"/gs ;} elsif ( $default && ( $default =~ /^'(.*?)'$/ ) ) { $default = $1 ; $default =~ s/\\'/'/gs ;} $elements{$element}->{attributes}->{$name} = [$type,$option,$default,undef]; push(@{$elements{$element}->{attr_order}} , $name) ; if ($type =~ /^(?:NOTATION\s*)?\(\s*(.*?)\)$/) { $elements{$element}->{attributes}->{$name}->[3] = parse_values($1); } } } $xml =~ s/\s+/ /gs ; if ( $xml =~ /^\s*<\!DOCTYPE\s+($name)\s*\[\s*(.*)$/ ) { $this->{root} = $1 ; my $data = $2 ; $data =~ s/\s*]\s*>\s*$//gi ; $xml = $data ; } $this->error("UNPARSED DATA:\n$xml\n\n") if $xml =~ /\S/ ; foreach my $element (keys %elements) { foreach my $child (keys %{$elements{$element}->{children}}) { if ($child eq '#PCDATA') { delete $elements{$element}->{children}->{'#PCDATA'}; $elements{$element}->{content} = 1; } else { $this->error("Element $child referenced by $element was not found!") unless exists $elements{$child} ; if (exists $elements{$child}->{parent}) { push @{$elements{$child}->{parent}}, $element ;} else { $elements{$child}->{parent} = [$element] ;} $elements{$child}->{option} = $elements{$element}->{children}->{$child} ; } } if ( !%{$elements{$element}->{children}} ) { delete $elements{$element}->{children} ;} } return \%elements ; } ########## # CUTDTD # ########## sub CutDTD { my $this = shift ; if ( !@_ ) { push(@_ , $this->{DATA} ) ;} my $xml = read_data( shift(@_) ) ; my (%elements, %definitions) ; $xml =~ s/\r\n?/\n/gs ; my $dtd_data ; while ($xml =~ s{()}{}io) { $dtd_data .= "$1\n" ; } $xml =~ s{}{}gs ; $xml =~ s{<\?.*?\?>}{}gs ; while ($xml =~ s{()}{}io) { $dtd_data .= "$1\n" ; } { my $replacements = 0 ; 1 while ++$replacements < 1000 and $xml =~ s{([&%]$name);}{(exists $definitions{$1} ? $definitions{$1} : "$1\x01;")}ge; $this->error("Recursive or too many entities!") if $xml =~ m{([&%]$name);} ; } undef %definitions ; $xml =~ tr/\x01//d ; while ($xml =~ s{()}{}io) { $dtd_data .= "$1\n" ; } while ($xml =~ s{()}{}io) { $dtd_data .= "$1\n" ; } while ($xml =~ s{()}{}ios) { $dtd_data .= "$1\n" ; } if ( $xml =~ /^\s*<\!DOCTYPE\s+($name)\s*\[\s*/ ) { $dtd_data = "\n" ; } return $dtd_data ; } #################### # FLATTEN_CHILDREN # #################### sub flatten_children { my ( $children , $option ) = @_ ; if ($children =~ /\|/) { $children =~ s/(\|$name)/${1}?/gs ; $children =~ s{\|}{?,}g ; } if ($option) { $children =~ s/,/$option,/g ; $children .= $option ; } return $children ; } ##################### # SIMPLIFY_CHILDREN # ##################### sub simplify_children { my ( $children, $option ) = @_; 1 while $children =~ s{\(($nameX(?:[,|]$nameX)*)\)([\?\*\+]*)}{flatten_children($1, $2)}geo ; if ($option) { $children =~ s/,/$option,/g ; $children .= $option ; } foreach ($children) { s{\?\?}{?}g; s{\?\+}{*}g; s{\?\*}{*}g; s{\+\?}{*}g; s{\+\+}{+}g; s{\+\*}{*}g; s{\*\?}{*}g; s{\*\+}{*}g; s{\*\*}{*}g; } return $children ; } ################ # PARSE_VALUES # ################ sub parse_values { my $def = shift ; $def =~ s/^\s*\(\s*// ; $def =~ s/\s*\)\s*$// ; $def = "|$def" ; my @def ; while( $def =~ /\s*|\s*(?:($RE_quoted)|([^\(\)\|]+))/gs ) { if ( defined $1 ) { my $q = $1 ; if ( $q =~ /^"(.*?)"$/ ) { $q = $1 ; $q =~ s/\\"/"/gs ;} elsif ( $q =~ /^'(.*?)'$/ ) { $q = $1 ; $q =~ s/\\'/'/gs ;} push(@def , $q) ; } elsif ( defined $2 ) { my $d = $2 ; $d =~ tr/\x20\x09\x0D\x0A//d ; # get rid of whitespace push(@def , $d) ; } } foreach my $def_i ( @def ) { } return \@def ; } ############# # READ_DATA # ############# sub read_data { my $data ; { my ($fh,$open) ; if (ref($_[0]) eq 'GLOB') { $fh = $_[0] ;} elsif ($_[0] =~ /^http:\/\/\w+[^\r\n]+$/s) { $data = &get_url($_[0]) ;} elsif ($_[0] =~ /<.*?>/s) { $data = $_[0] ;} else { open ($fh,$_[0]) ; binmode($fh) ; $open = 1 ;} if ($fh) { 1 while( read($fh, $data , 1024*8 , length($data) ) ) ; close($fh) if $open ; } } return $data ; } ################################################################################ ############# # APPLY_DTD # ############# sub apply_dtd { my $xml = shift ; my $dtd = shift ; if ( ref($dtd) ne 'XML::Smart::DTD' ) { $dtd = XML::Smart::DTD->new($dtd , @_) ;} $$xml->{DTD} = $dtd ; return if !$dtd || !$dtd->tree || !%{ $dtd->tree } ; _apply_dtd($dtd , $xml->tree , undef , undef , {} , undef , undef , {} , @_) ; } sub _apply_dtd { my ($dtd , $tree , $tag , $ar_i , $prev_tree , $prev_tag , $prev_exists , $parsed , %opts) = @_ ; _unset_sig_warn() ; ##print "$tag>> $tree , $tag , $prev_tree , $prev_tag , $parsed >> $opts{no_delete}\n" ; if ( ref($tree) ) { if ($$parsed{"$tree"}) { _reset_sig_warn() ; return ; } ++$$parsed{"$tree"} ; } if (ref($tree) eq 'HASH') { if ( $tag ne '' && $dtd->elem_exists($tag) ) { if ( $dtd->is_elem_empty($tag) ) { $prev_tree->{$tag} = {} ; } elsif ( $dtd->is_elem_pcdata($tag) ) { if ( ref $prev_tree->{$tag} eq 'HASH' ) { $prev_tree->{$tag}{CONTENT} = '' if !defined $prev_tree->{$tag}{CONTENT} ;} else { $prev_tree->{$tag} = '' if !defined $prev_tree->{$tag} ;} } else { my @childs_req = $dtd->get_childs_req($tag) ; foreach my $childs_req_i ( @childs_req ) { if ( !exists $tree->{$childs_req_i} ) { $tree->{$childs_req_i} = {} ; } } my @attrs_req = $dtd->get_attrs_req($tag) ; foreach my $attrs_req_i ( @attrs_req ) { if ( !exists $tree->{$attrs_req_i} ) { $tree->{$attrs_req_i} = $dtd->get_attr_def($tag , $attrs_req_i) ; } } { my @order = ($dtd->get_attrs($tag) , $dtd->get_childs($tag)) ; if ( ! $tree->{'/order'} ) { $tree->{'/order'} = \@order ;} else { my %in_order ; { my %n ; %in_order = map { $_ => (++$n{$_}) } @{ $tree->{'/order'} } ; } my (@new_order , %order) ; foreach my $order_i ( @order ) { _unset_sig_warn() ; push(@new_order , (($order_i) x ($in_order{$order_i} || 1))) ; $order{$order_i} = 1 ; _reset_sig_warn() ; } foreach my $order_i ( @{ $tree->{'/order'} } ) { next if $order{$order_i} ; push(@new_order , $order_i) ; } $tree->{'/order'} = \@new_order ; } } } } foreach my $Key ( keys %$tree ) { if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes' || $Key eq 'CONTENT') { next ;} if ( ( $tag eq '' && $dtd->elem_exists($Key)) || ( $tag ne '' && $dtd->child_exists($tag , $Key)) ) { if ( $tree->{'/nodes'}{$Key} && ( $tree->{'/nodes'}{$Key} =~ /^(\w+,\d+),(\d*)/ ) ) { $tree->{'/nodes'}{$Key} = "$1,1" ;} else { $tree->{'/nodes'}{$Key} = 1 ;} if ( !ref($tree->{$Key}) ) { my $content = ( $tree->{$Key} ) ? $tree->{$Key} : ''; $tree->{$Key} = {} if !ref $tree->{$Key} ; $tree->{$Key}{CONTENT} = $content if $content ne '' ; } elsif ( ref($tree->{$Key}) eq 'ARRAY' ) { if ( $tag ne '' && !$dtd->is_elem_child_multi($tag , $Key) ) { $tree->{$Key} = $tree->{$Key}[0] ; } } _apply_dtd($dtd , $tree->{$Key} , $Key , undef , $tree , $tag , 1, $parsed , %opts) ; } elsif ( $tag ne '' && $dtd->attr_exists($tag , $Key) ) { delete $tree->{'/nodes'}{$Key} ; if ( ref($tree->{$Key}) eq 'HASH' && exists $tree->{$Key}{CONTENT} && (keys %{$tree->{$Key}}) == 1 ) { my $content = $tree->{$Key}{CONTENT} ; $tree->{$Key} = $content ; } if ( ref $tree->{$Key} ) { if ( ref $tree->{$Key} eq 'ARRAY' ) { $tree->{$Key} = $tree->{$Key}[0] ;} if ( ref $tree->{$Key} eq 'HASH' ) { $tree->{$Key} = $tree->{$Key}{CONTENT} ;} } if ( $tag ne '' && $tree->{$Key} eq '' ) { $tree->{$Key} = $dtd->get_attr_def($tag , $Key) ; } } else { if ( $prev_exists && !$opts{no_delete} ) { delete $tree->{$Key} ;} else { _apply_dtd($dtd , $tree->{$Key} , $Key , undef , $tree , $tag , undef , $parsed , %opts) ; } } } } elsif (ref($tree) eq 'ARRAY') { my $i = -1 ; foreach my $tree_i ( @$tree ) { ++$i ; _apply_dtd($dtd , $tree_i , $tag , $i , $prev_tree , $prev_tag , $prev_exists , $parsed , %opts) ; } } else { if ( $tag ne '' && $dtd->elem_exists($tag) ) { if ( $prev_tree->{'/nodes'}{$tag} =~ /^(\w+,\d+),(\d*)/ ) { $prev_tree->{'/nodes'}{$tag} = "$1,1" ;} else { $prev_tree->{'/nodes'}{$tag} = 1 ;} if ( !ref($prev_tree->{$tag}) || ( ref($prev_tree->{$tag}) eq 'HASH' && !exists $prev_tree->{$tag}{CONTENT}) ) { my $content = $prev_tree->{$tag} ; $prev_tree->{$tag} = {} if !ref $prev_tree->{$tag} ; $prev_tree->{$tag}{CONTENT} = $content if $content ne '' ; } } elsif ( $tag ne '' && $dtd->attr_exists($prev_tag , $tag) ) { delete $prev_tree->{'/nodes'}{$tag} ; if ( ref($prev_tree->{$tag}) eq 'HASH' && exists $prev_tree->{$tag}{CONTENT} && (keys %{$prev_tree->{$tag}}) == 1 ) { my $content = $prev_tree->{$tag}{CONTENT} ; $prev_tree->{$tag} = $content ; } } } delete $$parsed{"$tree"} if ref($tree) ; _reset_sig_warn() ; return 1 ; } ####### # END # ####### 1; __END__ =head1 NAME XML::Smart::DTD - DTD parser for XML::Smart. =head1 DESCRIPTION This will parse DTD and provides methods to access the information stored in the DTD. =head1 USAGE use XML::Smart::DTD ; my $dtd = XML::Smart::DTD->new('some.dtd') ; if ( $dtd->child_exists('tag1','subtag1') ) { ... } use Data::Dumper ; print Dumper( $dtd->tree ) ; =head1 new =head1 METHODS =head2 attr_exists ( TAG , ATTR ) Return I if the attribute exists in the element TAG. =head2 child_exists ( TAG , CHILD ) Return I if the child exists in the element TAG. =head2 elem_exists ( TAG ) Return I if the element TAG exists. =head2 error Return the error list. =head2 get_attr_def ( TAG , ATTR ) Return the default value of an attribute =head2 get_attr_type ( TAG , ATTR ) Return the attribute type. =head2 get_attr_values ( TAG , ATTR ) Return the defined values of an attribute. =head2 get_attrs ( TAG ) Return the attribute list of a element. =head2 get_attrs_req ( TAG ) Return the required attribute list of a element. =head2 get_childs ( TAG ) Return the child list of an element. =head2 get_childs_req ( TAG ) Return the required child list of an element. =head2 get_elem_opt ( TAG ) Return the occurrence option of an element: ! REQUIRED AND ONLY ONE MATCH + 1 or more * 0 or more ? 0 or 1 =head2 get_elem_child_opt ( TAG , CHILD ) Same of I but this element as a child of an element. =head2 is_attr_fix ( TAG , ATTR ) Return I if an attribute is I. =head2 is_attr_req ( TAG , ATTR ) Return I if an attribute is I. =head2 is_elem_any ( TAG ) Return I if an element is I. =head2 is_elem_child_multi ( TAG , CHILD ) Return I if an element can have multiple occurrences as a child of TAG. =head2 is_elem_child_opt ( TAG , CHILD ) Return I if an element is optional as a child of TAG. =head2 is_elem_child_req ( TAG , CHILD ) Return I if an element is optional as a child of TAG. =head2 is_elem_child_uniq ( TAG , CHILD ) Return I if an element is required and unique as a child of TAG. =head2 is_elem_pcdata ( TAG ) Return I if an element is I (have content). =head2 is_elem_empty ( TAG ) Return I if an element is I (doesn't have attributes, content or children). =head2 is_elem_multi ( TAG ) Return I if an element can have multiple occurrences globally. =head2 is_elem_opt ( TAG ) Return I if an element is optional globally. =head2 is_elem_parent ( TAG , @PARENTS ) Return I if the list of @PARENTS can be parent of element TAG. =head2 is_elem_req Return I if an element is required globally. =head2 is_elem_uniq Return I if an element is unique and required globally. =head2 root Return the root name of the DTD. =head2 tree Return the HASH tree of the DTD. =head1 SEE ALSO L, L. =head1 AUTHOR Graciliano M. P. I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P =head1 THANKS Thanks to Jenda@Krynicky.cz http://Jenda.Krynicky.cz that is the author of L. =head1 COPYRIGHT The DTD parser was based on XML-DTDParser-1.7 by Jenda@Krynicky.cz http://Jenda.Krynicky.cz This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut XML-Smart-1.78/lib/XML/Smart/HTMLParser.pm0000644000175000017500000001267112214354637017304 0ustar harishharish############################################################################# ## Name: HTMLParser.pm ## Purpose: XML::Smart::HTMLParser ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 29/05/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::HTMLParser ; use 5.006 ; use strict ; use warnings ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION , @ISA) ; $VERSION = '1.12' ; ####### # NEW # ####### sub new { my $this = shift ; my $class = ref($this) || $this ; return $this if ref $this ; $this = bless {} => $class ; _unset_sig_warn() ; my %args = @_ ; _reset_sig_warn() ; $this->setHandlers(%args) ; $this->{NOENTITY} = 1 ; return $this ; } ############### # SETHANDLERS # ############### sub setHandlers { my $this = shift ; _unset_sig_warn() ; my %args = @_; _reset_sig_warn() ; $this->{Init} = $args{Init} || sub{} ; $this->{Start} = $args{Start} || sub{} ; $this->{Char} = $args{Char} || sub{} ; $this->{End} = $args{End} || sub{} ; $this->{Final} = $args{Final} || sub{} ; return( 1 ) ; } ######### # PARSE # ######### sub parse { my $this = shift ; my $data = shift ; $data =~ s/\r\n?/\n/gs ; $data =~ s/^\s*<\?xml.*?>//gsi ; my @parsed ; while( $data =~ /(.*?)<(.*?)>/gsi ) { my $cont = $1 ; my $markup = $2 ; my ( $more_q , @args ) = &parse_tag( $markup ) ; while( $more_q ) { my $more ; ( $more ) = ( $data =~ /\G(.*?)>/s ) ; pos( $data ) += length( $more ) + 1 ; $markup = $markup.'>'.$more ; ( $more_q , @args ) = &parse_tag( $markup ) ; } if( $cont =~ /\S/s ) { push( @parsed , 'Char' , $cont ) ; } if( $args[0] =~ /^\/(.*)/ ) { push( @parsed , 'End' , $1 ) ; } elsif( $args[-1] =~ /^\/$/ ) { pop @args ; push( @parsed , 'StartEnd' , [@args] ) ; } else { push( @parsed , 'Start' , [@args] ) ; } } { my ( %close, @close, %open ) ; for( my $i = ( $#parsed-1 ); $i >= 0; $i-=2 ) { my $type = $parsed[$i] ; if( $type eq 'End' ) { my $tag = $parsed[ $i+1 ] ; $close{ lc( $tag ) }++ ; push( @close , $i ) ; } elsif ( $type eq 'Start' ) { my $tag = @{ $parsed[$i+1] }[0] ; if( !$close{lc($tag)} ) { if( @{$parsed[$i+1]}[-1] eq '/' && $#{$parsed[$i+1]} % 2 ) { pop @{$parsed[$i+1]} ; $parsed[$i] = 'StartEnd' ; } elsif( $parsed[$i+2] ne 'Char') { $parsed[$i] = 'StartEnd' ; } else { push( @{ $open{$close[-1]} } , 'End' , $tag ) ; } } else { $close{lc($tag)}-- ; pop(@close) ; } } } if ( %open ) { my @parsed2 ; for( my $i=0 ; $i <= $#parsed ; ++$i ) { push( @parsed2, @{$open{ $i } } ) if $open{ $i } ; push( @parsed2, $parsed[ $i ] ) ; } @parsed = @parsed2 ; } } &{$this->{Init}}($this) ; for( my $i = 0 ; $i <= $#parsed ; $i+=2 ) { my $type = $parsed[ $i ] ; my $args = $parsed[ $i+1 ] ; if ($type eq 'Start' ) { &{$this->{Start}}( $this , ref($args) ? @{$args} : $args ) ;} elsif ($type eq 'Char' ) { &{$this->{Char}}( $this , ref($args) ? @{$args} : $args ) ;} elsif ($type eq 'End' ) { &{$this->{End}}( $this , ref($args) ? @{$args} : $args ) ;} elsif ($type eq 'StartEnd') { &{$this->{Start}}( $this , ref($args) ? @{$args} : $args ) ; &{$this->{End}}( $this , ref($args) ? @{$args}[0] : $args ) ; } } return &{$this->{Final}}($this) ; } ############# # PARSE_TAG # ############# sub parse_tag { my $args = shift ; #print "[$args]\n" ; if ($args =~ /^!--/s) { if ($args !~ /--$/s) { return('--') ;} $args =~ s/^!--//s ; $args =~ s/--$//s ; return('' , '!--' , 'CONTENT' , $args ) ; } my @args ; my ($type , $type_last) = (-1,-1) ; while($args =~ /(?:^\s*)?(?: ( \w+:\/\/[^'"\s]+ ## URI without quotes | [\w:\.-]+ ## words ) | ([^'"=\s]+) ## unquoted values | (=) ## equal between name and value | ## Quote: '...' (' (?: ' | (?:(?:\\')?[^'])+(?:'{1,2}|.*) ) ) | ## Quote: "..." (" (?: " | (?:(?:\\")?[^"])+(?:"{1,2}|.*) ) ) )/gsx) { my $got ; _unset_sig_warn() ; if ($1 ne '') { $got = $1 ;} elsif ($2 ne '') { $got = $2 ;} elsif ($3 ne '') { $got = $3 ;} elsif ($4 ne '') { $got = $4 ;} elsif ($5 ne '') { $got = $5 ;} else { _reset_sig_warn() ; next ; } _reset_sig_warn() ; if ($got =~ /^(['"])/s) { my $q = $1 ; if ($got !~ /$q$/s || $got =~ /\\$q$/s) { return($q) ;} else { $got =~ s/^$q//s ; $got =~ s/$q$//s ;} } if ($got eq '=') { $type = 1 ;} else { if ($type_last == 0 && $type == 0) { push(@args , '') ;} push(@args , $got) ; $type_last = $type ; $type = 0 ; } } #print "@args\n" ; return( '' , @args ) ; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart/Tree.pm0000644000175000017500000004133512214354761016257 0ustar harishharish############################################################################# ## Name: Tree.pm ## Purpose: XML::Smart::Tree ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 10/05/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::Tree ; use strict ; use warnings ; use Carp ; use XML::Smart::Entity qw(_parse_basic_entity) ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION) ; $VERSION = '1.34' ; my %PARSERS = ( XML_Parser => 0 , XML_Smart_Parser => 0 , XML_Smart_HTMLParser => 0 , ) ; ## BUG - By making DEFAULT_LOADED a global variable it is working across objects! ( Watch for possible usage elsewhere ) # my $DEFAULT_LOADED ; use vars qw($NO_XML_PARSER); ################### # LOAD_XML_PARSER # ################### sub load_XML_Parser { return if $NO_XML_PARSER ; _unset_sig_warn() ; eval('use XML::Parser ;') ; _reset_sig_warn() ; if ($@) { $@ = undef ; return( undef ) ;} my ($xml , $tree) ; _unset_sig_warn() ; eval { no strict ; my $data = '' ; $xml = XML::Parser->new(Style => 'Tree') ; $tree = $xml->parse($data) ; } ; _reset_sig_warn() ; if (!$tree || ref($tree) ne 'ARRAY') { return( undef ) ;} if ($tree->[1][2][0]{arg1} eq 't1') { return( 1 ) ;} return( undef ) ; } ######################### # LOAD_XML_SMART_PARSER # ######################### sub load_XML_Smart_Parser { _unset_sig_warn() ; eval('use XML::Smart::Parser ;') ; _reset_sig_warn() ; if ($@) { $@ = undef ; return( undef ) ;} return(1) ; } ############################# # LOAD_XML_SMART_HTMLPARSER # ############################# sub load_XML_Smart_HTMLParser { _unset_sig_warn() ; eval('use XML::Smart::HTMLParser ;') ; _reset_sig_warn() ; if ($@) { $@ = undef ; return( undef ) ;} return(1) ; } ######## # LOAD # ######## sub load { my ( $parser ) = @_ ; my $module ; my $DEFAULT_LOADED ; if ($parser) { $parser =~ s/:+/_/gs ; $parser =~ s/\W//g ; if ($parser =~ /^(?:html?|wild)$/i) { $parser = 'XML_Smart_HTMLParser' ;} elsif ($parser =~ /^(?:re|smart)/i) { $parser = 'XML_Smart_Parser' ;} foreach my $Key ( keys %PARSERS ) { if ($Key =~ /^$parser$/i) { $module = $Key ; last ;} } } my $ok ; if( $module && ( $module eq 'XML_Parser' ) ) { $PARSERS{XML_Parser} = 1 if &load_XML_Parser() ; $ok = $PARSERS{XML_Parser} ; } elsif ( $module && ( $module eq 'XML_Smart_Parser' ) ) { $PARSERS{XML_Smart_Parser} = 1 if !$PARSERS{XML_Smart_Parser} && &load_XML_Smart_Parser() ; $ok = $PARSERS{XML_Smart_Parser} ; } elsif( $module and ( $module eq 'XML_Smart_HTMLParser' ) ) { $PARSERS{XML_Smart_HTMLParser} = 1 if !$PARSERS{XML_Smart_HTMLParser} && &load_XML_Smart_HTMLParser() ; $ok = $PARSERS{XML_Smart_HTMLParser} ; } if (!$ok && !$DEFAULT_LOADED) { $PARSERS{XML_Parser} = 1 if &load_XML_Parser() ; $module = 'XML_Parser' ; if ( !$PARSERS{XML_Parser} ) { $PARSERS{XML_Smart_Parser} = 1 if &load_XML_Smart_Parser() ; $module = 'XML_Smart_Parser' ; } $DEFAULT_LOADED = 1 ; } return($module) ; } ######### # PARSE # ######### sub parse { my $module = $_[1] ; my $data ; { my ($fh,$open) ; if (ref($_[0]) eq 'GLOB') { $fh = $_[0] ;} elsif ($_[0] =~ /^http:\/\/\w+[^\r\n]+$/s) { $data = &get_url($_[0]) ;} elsif ($_[0] =~ /<.*?>/s) { $data = $_[0] ;} else { open ($fh,$_[0]) or croak( $! ); binmode($fh) ; $open = 1 ; } if ($fh) { no warnings ; 1 while( read($fh, $data , 1024*8 , length($data) ) ) ; close($fh) if $open ; } } if ($data !~ /<.*?>/s) { return( {} ) ;} if (!$module || !$PARSERS{$module}) { if ( !$NO_XML_PARSER && $INC{'XML/Parser.pm'} && $PARSERS{XML_Parser}) { $module = 'XML_Parser' ;} elsif ($PARSERS{XML_Smart_Parser}) { $module = 'XML_Smart_Parser' ;} } my $xml ; if ($module eq 'XML_Parser') { $xml = XML::Parser->new() ;} elsif ($module eq 'XML_Smart_Parser') { $xml = XML::Smart::Parser->new() ;} elsif ($module eq 'XML_Smart_HTMLParser') { $xml = XML::Smart::HTMLParser->new() ;} else { croak("Can't find a parser for XML!") ;} shift(@_) ; if ( $_[0] && ( $_[0] =~ /^\s*(?:XML_\w+|html?|re\w+|smart)\s*$/i ) ) { shift(@_) ;} _unset_sig_warn() ; my ( %args ) = @_ ; _reset_sig_warn() ; if ( $args{lowtag} ) { $xml->{SMART}{tag} = 1 ;} if ( $args{upertag} ) { $xml->{SMART}{tag} = 2 ;} if ( $args{lowarg} ) { $xml->{SMART}{arg} = 1 ;} if ( $args{uperarg} ) { $xml->{SMART}{arg} = 2 ;} if ( $args{arg_single} ) { $xml->{SMART}{arg_single} = 1 ;} if ( $args{no_order} ) { $xml->{SMART}{no_order} = 1 ;} if ( $args{no_nodes} ) { $xml->{SMART}{no_nodes} = 1 ;} if ( $args{use_spaces} ) { $xml->{SMART}{use_spaces} = 1 ;} $xml->{SMART}{on_start} = $args{on_start} if ref($args{on_start}) eq 'CODE' ; $xml->{SMART}{on_char} = $args{on_char} if ref($args{on_char}) eq 'CODE' ; $xml->{SMART}{on_end} = $args{on_end} if ref($args{on_end}) eq 'CODE' ; $xml->setHandlers( Init => \&_Init , Start => \&_Start , Char => \&_Char , End => \&_End , Final => \&_Final , ) ; my $tree ; eval { $tree = $xml->parse($data); }; croak( $@ ) if( $@ ); return( $tree ) ; } ################################################## ## UNUSED - DEPRECATED. ## ################################################## sub _clean_data_with_lt { my $data = shift ; my @data = split( //, $data ) ; my $data_len = @data ; # State Machine Definition: my %state_machine = ( 'in_cdata_block' => 0 , 'seen_some_tag' => 0 , 'need_to_cdata_this' => 0 , 'prev_lt' => -1 , 'last_tag_start' => -1 , 'last_tag_close' => -1 , 'tag_balance' => 0 , ); CHAR: for( my $index = 0; $index < $data_len; $index++ ) { { no warnings ; next CHAR unless( $data[ $index ] eq '<' or $data[ $index ] eq '>' ) ; } if( $data[ $index ] eq '<' ) { next CHAR if( $state_machine{ 'in_cdata_block' } ) ; { # Check for possibility of this being a cdata block my $possible_cdata_block = join( '', @data[ $index .. ( $index + 8 ) ] ) ; if( $possible_cdata_block eq '' ) { if( $state_machine{ 'in_cdata_block' } ) { my $possible_cdata_close = join( '', @data[ ( $index - 2 ) .. $index ] ) ; if( $possible_cdata_close eq ']]>' ) { $state_machine{ 'in_cdata_block' } = 0 ; $state_machine{ 'tag_balance' } = 0 ; next CHAR ; } next CHAR ; } unless( $state_machine{ 'seen_some_tag' } ) { croak " > found before < - Input XML seems to have errors!\n"; } $state_machine{ 'tag_balance' }-- ; unless( $state_machine{ 'tag_balance' } ) { $state_machine{ 'last_tag_close' } = $index ; next CHAR ; } ## Need to add CDATA now. my $last_tag_close = $state_machine{ 'last_tag_close' } ; my $prev_lt = $state_machine{ 'prev_lt' } ; $data[ $last_tag_close ] = '><' ; $state_machine{ 'last_tag_close' } = $index ; $state_machine{ 'need_to_cdata_this' } = 0 ; $state_machine{ 'tag_balance' } = 0 ; } } $data = join( '', @data ) ; return $data; } ########### # GET_URL # ########### sub get_url { my ( $url ) = @_ ; my $data ; require LWP ; require LWP::UserAgent ; my $ua = LWP::UserAgent->new(); my $agent = $ua->agent() ; $agent = "XML::Smart/$XML::Smart::VERSION $agent" ; $ua->agent($agent) ; my $req = HTTP::Request->new(GET => $url) ; my $res = $ua->request($req) ; if ($res->is_success) { return $res->content ;} else { return undef ;} } ########## # MODULE # ########## sub module { foreach my $Key ( keys %PARSERS ) { if ($PARSERS{$Key}) { my $module = $Key ; $module =~ s/_/::/g ; return( $module ) ; } } return('') ; } ######### # _INIT # ######### sub _Init { my $this = shift ; $this->{PARSING}{tree} = {} ; $this->{PARSING}{p} = $this->{PARSING}{tree} ; return ; } ########## # _START # ########## sub _Start { my $this = shift ; if ( $this->{LAST_CALL} && ( $this->{LAST_CALL} eq 'char' ) ) { _Char_process( $this , delete $this->{CONTENT_BUFFER} ) ; } ##print "START>> @_\n" ; $this->{LAST_CALL} = 'start' ; _unset_sig_warn(); my ( $tag , %args ) = @_ ; _reset_sig_warn(); if ( $this->{SMART}{tag} && ( $this->{SMART}{tag} == 1 ) ) { $tag = lc($tag) ;} elsif ( $this->{SMART}{tag} && ( $this->{SMART}{tag} == 2 ) ) { $tag = uc($tag) ;} $this->{PARSING}{p}{'/nodes'}{$tag} = 1 if !$this->{SMART}{no_nodes} ; push( @{$this->{PARSING}{p}{'/order'}} , $tag) if !$this->{SMART}{no_order} ; if ( $this->{SMART}{arg} ) { my $type = $this->{SMART}{arg} ; my %argsok ; foreach my $Key ( keys %args ) { my $k ; if ($type == 1) { $k = lc($Key) ;} elsif ($type == 2) { $k = uc($Key) ;} if (exists $argsok{$k}) { if ( ref $argsok{$k} ne 'ARRAY' ) { my $key = $argsok{$k} ; $argsok{$k} = [$key] ; } push(@{$argsok{$k}} , $args{$Key}) ; } else { $argsok{$k} = $args{$Key} ;} } %args = %argsok ; } if ( $this->{SMART}{arg_single} ) { foreach my $Key ( keys %args ) { $args{$Key} = 1 if !defined $args{$Key} ; } } ## Args order: if ( !$this->{SMART}{no_order} ) { my @order ; for(my $i = 1 ; $i < $#_ ; $i+=2) { push( @order , $_[$i] ) ;} if ( $this->{SMART}{arg} ) { my $type = $this->{SMART}{arg} ; foreach my $order_i ( @order ) { if ($type == 1) { $order_i = lc($order_i) ;} elsif ($type == 2) { $order_i = uc($order_i) ;} } } $args{'/order'} = \@order if @order ; } $args{'/tag'} = $tag ; $args{'/back'} = $this->{PARSING}{p} ; if ($this->{NOENTITY}) { foreach my $Key ( keys %args ) { &_parse_basic_entity( $args{$Key} ) ;} } if ( defined $this->{PARSING}{p}{$tag} ) { if ( ref($this->{PARSING}{p}{$tag}) ne 'ARRAY' ) { my $prev = $this->{PARSING}{p}{$tag} ; $this->{PARSING}{p}{$tag} = [$prev] ; } push(@{$this->{PARSING}{p}{$tag}} , \%args) ; my $i = @{$this->{PARSING}{p}{$tag}} ; $i-- ; $args{'/i'} = $i ; $this->{PARSING}{p} = \%args ; } else { $this->{PARSING}{p}{$tag} = \%args ; ## Change the pointer: $this->{PARSING}{p} = \%args ; } if ( $this->{SMART}{on_start} ) { my $sub = $this->{SMART}{on_start} ; &$sub($tag , $this->{PARSING}{p} , $this->{PARSING}{p}{'/back'} , undef , $this ) ; } return ; } ######### # _CHAR # ######### # # XML::Parser parse each line as a different call to _Char(). # For XML::Smart multiple calls to _Char() occurs only when the content # have other nodes inside. # sub _Char { ##print "CHAR>>\n" ; my $this = shift ; $this->{CONTENT_BUFFER} .= $_[0] ; $this->{LAST_CALL} = 'char' ; return ; } sub _Char_process { my $this = shift ; ##print "CONT>> ##@_##\n" ; my $content = $_[0] ; if ( !$this->{SMART}{use_spaces} && $content !~ /\S+/s ) { return ;} ###### if (! defined $this->{PARSING}{p}{'dt:dt'} && defined $this->{PARSING}{p}{'DT:DT'}) { $this->{PARSING}{p}{'dt:dt'} = delete $this->{PARSING}{p}{'DT:DT'} ; } if ( $this->{PARSING}{p}{'dt:dt'} && ( $this->{PARSING}{p}{'dt:dt'} =~ /binary\.base64/si ) ) { require XML::Smart::Base64 ; $content = &XML::Smart::Base64::decode_base64($content) ; delete $this->{PARSING}{p}{'dt:dt'} ; if ( $this->{PARSING}{p}{'/nodes'} ) { delete $this->{PARSING}{p}{'/nodes'}{'dt:dt'} ; my $nkeys = keys %{$this->{PARSING}{p}{'/nodes'}} ; if ($nkeys < 1) { delete $this->{PARSING}{p}{'/nodes'} ;} } if ( $this->{PARSING}{p}{'/order'} ) { my @order = @{$this->{PARSING}{p}{'/order'}} ; my @order_ok ; foreach my $order_i ( @order ) { push(@order_ok , $order_i) if $order_i ne 'dt:dt' ;} if (@order_ok) { $this->{PARSING}{p}{'/order'} = \@order_ok ;} else { delete $this->{PARSING}{p}{'/order'} ;} } } elsif ($this->{NOENTITY}) { &_parse_basic_entity($content) ;} ###### if ( !exists $this->{PARSING}{p}{CONTENT} ) { $this->{PARSING}{p}{CONTENT} = $content ; push(@{$this->{PARSING}{p}{'/order'}} , 'CONTENT') if !$this->{SMART}{no_order} ; } else { if ( !tied $this->{PARSING}{p}{CONTENT} ) { my $cont = $this->{PARSING}{p}{CONTENT} ; $this->{PARSING}{p}{CONTENT} = '' ; my $tied = tie( $this->{PARSING}{p}{CONTENT} => 'XML::Smart::TieScalar' , $this->{PARSING}{p}) ; push(@{$this->{TIED_CONTENTS}} , $tied) ; $this->{PARSING}{p}{'/.CONTENT/x'} = 0 ; $this->{PARSING}{p}{"/.CONTENT/0"} = $cont ; my $cont_pos = 0 ; for my $key ( @{$this->{PARSING}{p}{'/order'}} ) { last if ($key eq 'CONTENT') ; ++$cont_pos ; } splice( @{$this->{PARSING}{p}{'/order'}} , $cont_pos,0, "/.CONTENT/0") if !$this->{SMART}{no_order} ; } my $x = ++$this->{PARSING}{p}{'/.CONTENT/x'} ; $this->{PARSING}{p}{"/.CONTENT/$x"} = $content ; push( @{$this->{PARSING}{p}{'/order'}} , "/.CONTENT/$x") if !$this->{SMART}{no_order} ; } if ( $this->{SMART}{on_char} ) { my $sub = $this->{SMART}{on_char} ; &$sub($this->{PARSING}{p}{'/tag'} , $this->{PARSING}{p} , $this->{PARSING}{p}{'/back'} , \$this->{PARSING}{p}{CONTENT} , $this ) ; } return ; } ######## # _END # ######## sub _End { ##print "END>> @_[1] >> $_[0]->{PARSING}{p}{'/tag'}\n" ; my $this = shift ; if ( $this->{LAST_CALL} eq 'char' ) { _Char_process( $this , delete $this->{CONTENT_BUFFER} ) ;} $this->{LAST_CALL} = 'end' ; my $tag = shift ; if ( $this->{SMART}{tag} && ( $this->{SMART}{tag} == 1 ) ) { $tag = lc($tag) ;} elsif ( $this->{SMART}{tag} && ( $this->{SMART}{tag} == 2 ) ) { $tag = uc($tag) ;} if ( $this->{PARSING}{p}{'/tag'} ne $tag ) { return ;} delete $this->{PARSING}{p}{'/tag'} ; my $back = delete $this->{PARSING}{p}{'/back'} ; my $i = delete $this->{PARSING}{p}{'/i'} || 0 ; my $nkeys = keys %{$this->{PARSING}{p}} ; if ( $nkeys == 1 && exists $this->{PARSING}{p}{CONTENT} ) { if (ref($back->{$tag}) eq 'ARRAY') { $back->{$tag}[$i] = $this->{PARSING}{p}{CONTENT} ;} else { $back->{$tag} = $this->{PARSING}{p}{CONTENT} ;} } if ( $this->{PARSING}{p}{'/nodes'} && !%{$this->{PARSING}{p}{'/nodes'}} ) { delete $this->{PARSING}{p}{'/nodes'} ;} if ( $this->{PARSING}{p}{'/order'} && $#{$this->{PARSING}{p}{'/order'}} <= 0 ) { delete $this->{PARSING}{p}{'/order'} ;} delete $this->{PARSING}{p}{'/.CONTENT/x'} ; if ( $this->{SMART}{on_end} ) { my $sub = $this->{SMART}{on_end} ; &$sub($tag , $this->{PARSING}{p} , $back , undef , $this) ; } $this->{PARSING}{p} = $back ; return ; } ########## # _FINAL # ########## sub _Final { my $this = shift ; my $tree = $this->{PARSING}{tree} ; foreach my $tied_cont ( @{$this->{TIED_CONTENTS}} ) { $tied_cont->_cache_keys ; } delete $this->{TIED_CONTENTS} ; delete $this->{LAST_CALL} ; delete($this->{PARSING}) ; return($tree) ; } ####### # END # ####### 1; __END__ XML-Smart-1.78/lib/XML/Smart/FAQ.epod0000644000175000017500000001212410110165501016255 0ustar harishharish=> NAME XML::Smart::FAQ - Frequently Asked Questions about XML::Smart. => SYNOPSIS This is the Frequently Asked Questions list for XML::Smart. => QUESTIONS B ==> Do I need to install XML::Parser to can use XML::Smart? No! XML::Smart already comes with 2 independent parsers, XML::Smart::Parser and XML::Smart::HTMLParser. If L is found XML::Smart will use it by default, and the 2nd options will be XML::Smart::Parser. Note that for complex parsing L is recommended, but XML::Smart::Parser will work fine too. ==> What is the best version of XML::Smart to install? Is always the last! Always take a look for new versions before aks for help on XML::Smart. Note that internally XML::Smart is complex, since the main idea of it is to remove the complexity from the hand of the programmer. Actually the idea is to enable the Perl programmer to use and create XML data without really know the XML format. ==> Where can I learn about XML? http://www.xml.com ==> How to apply a DTD to a XML::Smart object tree? Take a look in the method I. Example of use: $xml->apply_dtd(q` ]> `); This will format automatically elements, attributes, etc... ==> How XML::Smart works? To create I, first I have created the module L. With it you can have an object that works at the same time as a HASH, ARRAY, SCALAR, CODE & GLOB. So you can do things like this with the same object: $obj = Object::MultiType->new() ; $obj->{key} ; $obj->[0] ; $obj->method ; @l = @{$obj} ; %h = %{$obj} ; &$obj(args) ; print $obj "send data\n" ; Seems to be crazy, and can be more if you use tie() inside it, and this is what I does. For I, the access in the Hash and Array way paste through tie(). In other words, you have a tied HASH and tied ARRAY inside it. This tied Hash and Array work together, soo B: %hash = ( key => ['a','b','c'] ) ; $hash->{key} ## return $hash{key}[0] $hash->{key}[0] ## return $hash{key}[0] $hash->{key}[1] ## return $hash{key}[1] ## Inverse: %hash = ( key => 'a' ) ; $hash->{key} ## return $hash{key} $hash->{key}[0] ## return $hash{key} $hash->{key}[1] ## return undef The best thing of this new resource is to avoid wrong access to the data and warnings when you try to access a Hash having an Array (and the inverse). Thing that generally make the script die(). Once having an easy access to the data, you can use the same resource to B data! For example: ## Previous data: ## Now you have {address} as a normal key with a string inside: $XML->{hosts}{server}{address} ## And to add a new address, the key {address} need to be an ARRAY ref! ## So, XML::Smart make the convertion: ;-P $XML->{hosts}{server}{address}[1] = '192.168.2.101' ; ## Adding to a list that you don't know the size: push(@{$XML->{hosts}{server}{address}} , '192.168.2.102') ; ## The data now:
192.168.2.100
192.168.2.101
192.168.2.102
Than after changing your XML tree using the Hash and Array resources you just get the data remade (through the Hash tree inside the object): my $xmldata = $XML->data ; B always return an object>! Even when you get a final key. So this actually returns another object, pointhing (inside it) to the key: $addr = $XML->{hosts}{server}{address}[0] ; ## Since $addr is an object you can TRY to access more data: $addr->{foo}{bar} ; ## This doens't make warnings! just return UNDEF. ## But you can use it like a normal SCALAR too: print "$addr\n" ; $addr .= ':80' ; ## After this $addr isn't an object any more, just a SCALAR! ==> When I generate the XML data new lines (\n) are added to the content! You should use the options for the method data() and save() to not add identation to the generated data: $XML->data( noident => 1 ) ; ## or better: $XML->data( nospace => 1 ) ; ==> Your question is not here? Just send me an e-mail. ;-P => AUTHOR Graciliano M. P. I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P => ePod This document was written in L (easy-POD), than converted to POD, and from here you know the way. XML-Smart-1.78/lib/XML/Smart/Shared.pm0000644000175000017500000001033312101147714016551 0ustar harishharishpackage XML::Smart::Shared ; use 5.006 ; use strict ; use warnings FATAL => 'all' ; use Exporter 'import' ; =head1 NAME XML::Smart::Shared - Shared functions and variables for XML::Smart. =head1 VERSION Version 0.01 =cut our $VERSION = '0.01'; =head1 SYNOPSIS Shared functions and variables for XML::Smart. =head1 EXPORT All functions are exported through export_ok =cut our @EXPORT_OK = qw(_unset_sig_warn _reset_sig_warn SIG_WARN _unset_sig_die _reset_sig_die SIG_DIE ); =head1 GLOBAL VARIABLES our ( $SIG_WARN , $SIG_DIE ) ; =cut my ( $SIG_WARN , $SIG_DIE ) ; =head1 SUBROUTINES/METHODS =head2 _unset_sig_warn This function saves current __WARN__ and sets it to none. =cut sub _unset_sig_warn { $SIG_WARN = $SIG{__WARN__} ; $SIG{__WARN__} = sub {} ; } =head2 _reset_sig_warn This function replaces __WARN__ with value saved by _unset_sig_warn =cut sub _reset_sig_warn { $SIG{__WARN__} = $SIG_WARN ; } =head2 _unset_sig_die This function saves current __DIE__ and sets it to none. =cut sub _unset_sig_die { $SIG_DIE = $SIG{__DIE__} ; $SIG{__DIE__} = sub {} ; } =head2 _reset_sig_die This function replaces __DIE__ with value saved by _unset_sig_warn =cut sub _reset_sig_die { $SIG{__DIE__} = $SIG_DIE ; } =head1 AUTHOR Harish Madabushi, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. Both the author and the maintainer will be notified, and then you'll automatically be notified of progress on your bug as changes are made. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc XML::Smart You can also look for information at: =over 5 =item * RT: CPAN's request tracker (report bugs here) L =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * Search CPAN L =item * GitHub CPAN L =back =head1 LICENSE AND COPYRIGHT Copyright 2013 Harish Madabushi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at: L Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =cut 1; # End of XML::Smart::Shared XML-Smart-1.78/lib/XML/Smart/Entity.pm0000644000175000017500000000362412101165165016624 0ustar harishharish############################################################################# ## Name: Entity.pm ## Purpose: XML::Smart::Entity - Handle entities ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 28/09/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::Entity ; use strict ; use warnings ; require Exporter ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION , @ISA) ; $VERSION = '0.03' ; @ISA = qw(Exporter) ; our @EXPORT = qw(_parse_basic_entity _add_basic_entity) ; our @EXPORT_OK = @EXPORT ; ####################### # _PARSE_BASIC_ENTITY # ####################### sub _parse_basic_entity { my $entity = $_[0] ; if( $entity ) { $_[0] =~ s/<//gs ; $_[0] =~ s/&/&/gs ; $_[0] =~ s/'/'/gs ; $_[0] =~ s/"/"/gs ; $_[0] =~ s/&#(\d+);/ $1 > 255 ? pack("U",$1) : pack("C",$1)/egs ; $_[0] =~ s/&#x([a-fA-F\d]+);/pack("U",hex($1))/egs ; } return( $entity ) ; } ##################### # _ADD_BASIC_ENTITY # ##################### sub _add_basic_entity { my $entity = $_[0] ; if( $entity ) { $_[0] =~ s/(&(?:\w+;)?)/{_is_amp($1) or $1}/sgex ; $_[0] =~ s//>/gs ; } return( $entity ) ; } ########### # _IS_AMP # ########### sub _is_amp { my $entity = $_[0] ; if( $entity ) { if($entity eq '&') { return( '&' ) ; } } return( undef ) ; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart/Data.pm0000644000175000017500000004561012214355024016222 0ustar harishharish############################################################################# ## Name: Data.pm ## Purpose: XML::Smart::Data - Generate XML data. ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 28/09/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart::Data ; use strict ; use warnings ; require Exporter ; use XML::Smart::Entity qw(_add_basic_entity) ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; our ($VERSION , @ISA) ; $VERSION = '0.06' ; @ISA = qw(Exporter) ; our @EXPORT = qw(data) ; our @EXPORT_OK = @EXPORT ; ######## # DATA # ######## sub data { _unset_sig_warn() ; my $this = shift ; my ( %args ) = @_ ; my $tree ; if( $args{tree} ) { $tree = $args{ tree } ; } else { $tree = $this->tree ; } { my $addroot ; if ( $args{root} || ref $tree ne 'HASH' ) { $addroot = 1 ; } else { my $ks = keys %$tree ; ## WARNING ON ORDER ( Mostly harmless )! my $n = 1 ; if (ref $$tree{'/nodes'} eq 'HASH') { ++$n ;} if (ref $$tree{'/order'} eq 'ARRAY') { ++$n ;} #if (ref $$tree{'/nodes'} eq 'HASH') { ++$n if (keys %{$$tree{'/nodes'}}) ;} #if (ref $$tree{'/order'} eq 'ARRAY') { ++$n if @{$$tree{'/order'}} ;} if ($ks > $n) { $addroot = 1 ; } else { # Fix hash randomization bug Id:84929 my %tmp = %$tree ; delete $tmp{ '/nodes' } ; delete $tmp{ '/order' } ; my $k = (keys %tmp)[0] ; if (ref $$tree{$k} eq 'ARRAY' && $#{$$tree{$k}} > 0) { my ($c,$ok) ; foreach my $i ( @{$$tree{$k}} ) { if ( $i && &is_valid_tree($i) ) { $c++ ; $ok = $i ;} if ($c > 1) { $addroot = 1 ; last ;} } if (!$addroot && $ok) { $$tree{$k} = $ok ;} } elsif (ref $$tree{$k} =~ /^(?:HASH|)$/) { $addroot = 1 ;} } } if ($addroot) { my $root = $args{root} || 'root' ; $tree = {$root => $tree} ; } } if ( $args{lowtag} ) { $args{lowtag} = 1 ;} if ( $args{upertag} ) { $args{lowtag} = 2 ;} if ( $args{lowarg} ) { $args{lowarg} = 1 ;} if ( $args{uperarg} ) { $args{lowarg} = 2 ;} my ($data,$unicode) ; { my $parsed = {} ; &_data( $args{decode}, \$data , $tree , '' , -1 , {} , $parsed , undef , undef , $args{noident} , $args{nospace} , $args{lowtag} , $args{lowarg} , $args{wild} , $args{sortall} ) ; $data .= "\n" if !$args{nospace} ; if ( &_is_unicode($data) ) { $unicode = 1 ;} } my $enc = 'iso-8859-1' ; if ($unicode) { $enc = 'UTF-8' ;} my $meta ; if ( $args{meta} ) { my @metas ; if (ref($args{meta}) eq 'ARRAY') { @metas = @{$args{meta}} ;} elsif (ref($args{meta}) eq 'HASH') { @metas = $args{meta} ;} else { @metas = $args{meta} ;} foreach my $metas_i ( @metas ) { if (ref($metas_i) eq 'HASH') { my $meta ; foreach my $Key (sort keys %$metas_i ) { $meta .= " $Key=" . &_add_quote($$metas_i{$Key}) ; } $metas_i = $meta ; } } foreach my $meta ( @metas ) { $meta =~ s/^[<\?\s*]//s ; $meta =~ s/[\s\?>]*$//s ; $meta =~ s/^meta\s+//s ; $meta = "" ; } $meta = "\n" . join ("\n", @metas) ; } my $wild = $args{wild} ? ' [format: wild]' : '' ; my $metagen = qq`\n` ; if ( $args{nometagen} ) { $metagen = '' ;} my $length ; if ( $args{length} ) { $length = ' length="' . (length($metagen) + length($meta) + length($data)) . '"' ; } my $xml = qq`` ; if ( $args{noheader} ) { $xml = '' ; $metagen = '' if $args{nometagen} eq '' ;} my $dtd ; if ( !$args{nodtd} && $$this->{DTD} ) { $dtd = ref $$this->{DTD} ? $$this->{DTD}->CutDTD : $$this->{DTD} ; $dtd =~ s/\s*$// ; $dtd = "\n$dtd" if $dtd ne '' && !$args{nospace} ; } $data = $xml . $metagen . $meta . $dtd . $data ; if ($xml eq '') { $data =~ s/^\s+//gs ;} if (wantarray) { _reset_sig_warn() ; return($data , $unicode) ; } _reset_sig_warn() ; return($data) ; } ################################################## ## UNUSED - DEPRECATED. ## ################################################## sub _replace_data_with_lt { my $data = shift ; while( my $index_of_smart_html_encode = index( $data, 'smart_html_encode( < )' ) ) { last if( $index_of_smart_html_encode == -1 ) ; my $tmp = substr( $data , $index_of_smart_html_encode , length( 'smart_html_encode( < )' ) , '<' ) ; } while( my $index_of_multiple_smart_html_encode = index( $data, 'multiple_smart_html_encode(' ) ) { last if( $index_of_multiple_smart_html_encode == -1 ) ; my $check_string = substr( $data, $index_of_multiple_smart_html_encode ) ; if( $check_string =~ /multiple_smart_html_encode\((.*?)\).*/ ) { my $params = $1 ; my $len = length( $params ) ; $params =~ s/^\s+//g; $params =~ s/\s+$//g; my ( $from, $to ) = split( /\s/, $params ) ; my $number_of_lt = $from - $to ; my $tmp = substr( $data, $index_of_multiple_smart_html_encode, length( 'multiple_smart_html_encode(' ) + $len + 1 , '<' x $number_of_lt ); } } return $data ; } ################# # IS_VALID_TREE # ################# sub is_valid_tree { _unset_sig_warn() ; my ( $tree ) = @_ ; my $found ; if (ref($tree) eq 'HASH') { foreach my $Key (sort keys %$tree ) { if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;} if (ref($$tree{$Key})) { $found = &is_valid_tree($$tree{$Key}) ;} elsif ($$tree{$Key} ne '') { $found = 1 ;} if ($found) { last ;} } } elsif (ref($tree) eq 'ARRAY') { foreach my $value (@$tree) { if (ref($value)) { $found = &is_valid_tree($value) ;} elsif ($value ne '') { $found = 1 ;} if ($found) { last ;} } } elsif (ref($tree) eq 'SCALAR' && $$tree ne '') { $found = 1 ;} _reset_sig_warn() ; return $found ; } ############### # _IS_UNICODE # ############### sub _is_unicode { _unset_sig_warn() ; if ($] >= 5.008001) { if ( utf8::is_utf8($_[0])) { _reset_sig_warn() ; return 1 ; } } elsif ($] >= 5.008) { require Encode ; if ( Encode::is_utf8($_[0])) { _reset_sig_warn() ; return 1 ; } } elsif ( $] >= 5.007 ) { _reset_sig_warn() ; my $is = eval(q` if ( $_[0] =~ /[\x{100}-\x{10FFFF}]/s) { return 1 ;} return undef ; `); $@ = undef ; return 1 if $is ; } else { ## No Perl internal support for UTF-8! ;-/ ## Is better to handle as Latin1. _reset_sig_warn() ; return undef ; } _reset_sig_warn() ; return undef ; } ######### # _DATA # ######### sub _data { _unset_sig_warn() ; my ( $decode, $data , $tree , $tag , $level , $prev_tree , $parsed , $ar_i , $node_type , @stat ) = @_ ; if (ref($tree) eq 'XML::Smart') { $tree = defined $$tree->{content} ? $$tree->{content} : $$tree->{point} ;} if ( ref($tree) ) { if ($$parsed{"$tree"}) { _reset_sig_warn() ; return ; } ++$$parsed{"$tree"} ; } my $ident = "\n" ; $ident .= ' ' x $level if !$stat[0] ; if ($stat[1]) { $ident = '' ;} $stat[1] -= 2 if $stat[1] > 1 ; my $tag_org = $tag ; $tag = $stat[4] ? $tag : &_check_tag($tag) ; if ($stat[2] == 1) { $tag = "\L$tag\E" ;} elsif ($stat[2] == 2) { $tag = "\U$tag\E" ;} if (ref($tree) eq 'HASH') { my ($args,$args_end,$tags,$cont,$stat_1) ; my (@all_keys , %multi_keys) ; if ( !$stat[5] && $tree->{'/order'} ) { my %keys ; foreach my $keys_i ( @{$tree->{'/order'}} ) { if ( exists $$tree{$keys_i} && (!ref($$tree{$keys_i}) || ref($$tree{$keys_i}) eq 'HASH' || ref($$tree{$keys_i}) eq 'XML::Smart' || (ref($$tree{$keys_i}) eq 'ARRAY' && exists $$tree{$keys_i}[ $keys{$keys_i} ] ) ) ) { push(@all_keys , $keys_i) ; if ( ++$keys{$keys_i} == 2 && ref $$tree{$keys_i} eq 'ARRAY' ) { my @val = map { ( $_ ne '' ? 1 : () ) } @{ $$tree{$keys_i} } ; $multi_keys{$keys_i} = 1 if $#val > 0 ; } } } foreach my $keys_i ( sort keys %$tree ) { if ( !$keys{$keys_i} && exists $$tree{$keys_i} ) { push(@all_keys , $keys_i) ;} } } else { @all_keys = sort keys %$tree ;} my %array_i ; foreach my $Key ( @all_keys ) { if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;} if ( $Key eq '!--' && (!ref($$tree{$Key}) || ( ref($$tree{$Key}) eq 'HASH' && (keys %{$$tree{$Key}}) == 1 && (defined $$tree{$Key}{CONTENT} || defined $$tree{$Key}{content}) ) ) ) { my $ct = $$tree{$Key} ; if (ref $$tree{$Key}) { $ct = defined $$tree{$Key}{CONTENT} ? $$tree{$Key}{CONTENT} : $$tree{$Key}{content} ;} ; if ( $ct ne '' ) { $tags .= "$ident" ;} } elsif (ref($$tree{$Key})) { my $k = $$tree{$Key} ; my $i ; if (ref $k eq 'XML::Smart') { $k = defined ${$$tree{$Key}}->{content} ? ${$$tree{$Key}}->{content} : ${$$tree{$Key}}->{point} ; } elsif ( ref $k eq 'ARRAY' && $multi_keys{$Key} ) { $i = $array_i{$Key}++ if $#{$k} > 0 ; } $args .= &_data($decode, \$tags,$k,$Key, $level+1 , $tree , $parsed , $i , $$tree{'/nodes'}{$Key} , @stat) if $array_i{$Key} ne 'ok' ; $array_i{$Key} = 'ok' if $i eq '' && ref $k eq 'ARRAY' ; } elsif ( $$tree{'/nodes'}{$Key} ) { my $k = [$$tree{$Key}] ; $args .= &_data($decode, \$tags,$k,$Key, $level+1 , $tree , $parsed , undef , $$tree{'/nodes'}{$Key} , @stat) ; } elsif (lc($Key) eq 'content') { if ( tied($$tree{$Key}) && $$tree{$Key} =~ /\S/s ) { $ident = '' ; $stat[1] += 2 ; } next if tied($$tree{$Key}) ; if ( $$tree{$Key} ne '' ) { my $p0 = length($tags) ; $tags .= $$tree{$Key} ; $cont = [$p0, length($tags) - $p0] ; } } elsif ($Key =~ /^\/\.CONTENT\/\d+$/) { $tags .= $$tree{$Key} ;} elsif ( $stat[4] && $$tree{$Key} eq '') { $args_end .= " $Key" ;} else { my $tp = _data_type($$tree{$Key}) ; if ($tp == 1) { my $k = $stat[4] ? $Key : &_check_key($Key) ; if ($stat[3] == 1) { $k = "\L$Key\E" ;} elsif ($stat[3] == 2) { $k = "\U$Key\E" ;} $args .= " $k=" . &_add_quote($$tree{$Key}) ; } else { my $k = $stat[4] ? $Key : &_check_key($Key) ; if ($stat[2] == 1) { $k = "\L$Key\E" ;} elsif ($stat[2] == 2) { $k = "\U$Key\E" ;} if ($tp == 2) { my $cont = $$tree{$Key} ; &_add_basic_entity($cont) ; $tags .= qq`$ident<$k>$cont` ; } elsif ($tp == 3) { $tags .= qq`$ident<$k>`;} elsif ($tp == 4) { require XML::Smart::Base64 ; my $base64 = &XML::Smart::Base64::encode_base64($$tree{$Key}) ; $base64 =~ s/\s$//s ; $tags .= qq`$ident<$k dt:dt="binary.base64">$base64`; } } } } # foreach my $Key ( @all_keys ) { -- Contains if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;} foreach my $Key ( keys %array_i ) { if ( $array_i{$Key} ne 'ok' && $#{ $$tree{$Key} } >= $array_i{$Key} ) { for my $i ( $array_i{$Key} .. $#{ $$tree{$Key} } ) { $args .= &_data($decode, \$tags, $$tree{$Key} ,$Key, $level+1 , $tree , $parsed , $i , $$tree{'/nodes'}{$Key} , @stat) ; } } } if ( $cont ne '' ) { my ( $po , $p1 ) = @$cont ; my $cont = substr($tags , $po , $p1) ; my $tp = _data_type($cont) ; if ( $node_type =~ /^(\w+),(\d+),(\d*)$/ ) { my ( $node_tp , $node_set ) = ($1,$2) ; if ( !$node_set ) { if ( $tp == 3 && $node_tp eq 'cdata' ) { $tp = 0 ;} elsif ( $tp == 4 && $node_tp eq 'binary' ) { $tp = 0 ;} } else { if ( $node_tp eq 'cdata' ) { $tp = 3 ;} elsif ( $node_tp eq 'binary' ) { $tp = 4 ;} } } if ( $tp == 3 ) { $cont = "" ;} elsif ( $tp == 4 ) { require XML::Smart::Base64 ; $cont = &XML::Smart::Base64::encode_base64($cont) ; $cont =~ s/\s$//s ; $args .= ' dt:dt="binary.base64"' ; } else { &_add_basic_entity($cont) ;} my $pe = $po + $p1 ; my $px = $pe ; while( substr($tags , $px , 1) =~ /\s/ ) { ++$px ;} if ( $px > $pe ) { substr($tags , $pe , $px-$pe) = '' ;} substr($tags , $po , $p1) = $cont ; } ## print STDERR "***$tag>> $args,$args_end,$tags,$cont,$stat_1 [@all_keys]\n" ; if ($args_end ne '') { $args .= $args_end ; $args_end = undef ; } if (!@all_keys) { $$data .= qq`$ident<$tag/>` if $tag ne '' ; } elsif ($args ne '' && $tags ne '') { if( $args =~ /dt\:dt="binary.base64"/ and $decode ) { $$data .= qq`$ident<$tag>` if $tag ne '' ; require XML::Smart::Base64 ; $$data .= &XML::Smart::Base64::decode_base64( $tags ) ; } else { $$data .= qq`$ident<$tag$args>` if $tag ne '' ; $$data .= $tags ; } $$data .= $ident if !$cont ; $$data .= qq`` if $tag ne '' ; } elsif ($args ne '') { $$data .= qq`$ident<$tag$args/>`; } elsif ($tags ne '') { $$data .= qq`$ident<$tag>` if $tag ne '' ; $$data .= $tags ; $$data .= $ident if !$cont ; $$data .= qq`` if $tag ne '' ; } else { $$data .= qq`$ident<$tag>` if $tag ne '' ; } } elsif (ref($tree) eq 'ARRAY') { my ($c,$v,$tags) ; foreach my $value_i ( ($ar_i ne '' ? $$tree[$ar_i] : @$tree) ) { my $value = $value_i ; if (ref $value_i eq 'XML::Smart') { $value = $$value_i->{point} ;} my $do_val = 1 ; if ( $tag_org eq '!--' && ( !ref($value) || ( ref($value) eq 'HASH' && keys %{$value} == 1 && (defined $$value{CONTENT} || defined $$value{content}) ) ) ) { $c++ ; my $ct = $value ; if (ref $value) { $ct = defined $$value{CONTENT} ? $$value{CONTENT} : $$value{content} ;} ; $tags .= $ident . '' ; $v = $ct if $c == 1 ; $do_val = 0 ; } elsif (ref($value)) { if (ref($value) eq 'HASH') { $c = 2 ; &_data($decode, \$tags,$value,$tag,$level, $tree , $parsed , undef , undef , @stat) ; $do_val = 0 ; } elsif (ref($value) eq 'SCALAR') { $value = $$value ;} elsif (ref($value) ne 'ARRAY') { $value = "$value" ;} } if ( $do_val && $value ne '') { my $tp = _data_type($value) ; if ( $node_type =~ /^(\w+),(\d+),(\d*)$/ ) { my ( $node_tp , $node_set ) = ($1,$2) ; if ( !$node_set ) { if ( $tp == 3 && $node_tp eq 'cdata' ) { $tp = 0 ;} elsif ( $tp == 4 && $node_tp eq 'binary' ) { $tp = 0 ;} } else { if ( $node_tp eq 'cdata' ) { $tp = 3 ;} elsif ( $node_tp eq 'binary' ) { $tp = 4 ;} } } if ($tp <= 2) { $c++ ; my $cont = $value ; &_add_basic_entity($value) ; &_add_basic_entity($cont) ; $tags .= qq`$ident<$tag>$cont`; $v = $cont if $c == 1 ; } elsif ($tp == 3) { $c++ ; $tags .= qq`$ident<$tag>`; $v = $value if $c == 1 ; } elsif ($tp == 4) { $c++ ; require XML::Smart::Base64 ; my $base64 = &XML::Smart::Base64::encode_base64($value) ; $base64 =~ s/\s$//s ; $tags .= qq`$ident<$tag dt:dt="binary.base64">$base64`; $v = $value if $c == 1 ; } } } if ( $ar_i eq '' && $c <= 1 && ! $$prev_tree{'/nodes'}{$tag}) { my $k = $stat[4] ? $tag : &_check_key($tag) ; if ($stat[3] == 1) { $k = "\L$k\E" ;} elsif ($stat[3] == 2) { $k = "\U$k\E" ;} delete $$parsed{"$tree"} if ref($tree) ; my $return_val = " $k=" . &_add_quote($v) ; _reset_sig_warn() ; return $return_val ; } else { $$data .= $tags ;} } elsif (ref($tree) eq 'SCALAR') { my $k = $stat[4] ? $tag : &_check_key($tag) ; if ($stat[3] == 1) { $k = "\L$k\E" ;} elsif ($stat[3] == 2) { $k = "\U$k\E" ;} delete $$parsed{"$tree"} if ref($tree) ; my $return_val = " $k=" . &_add_quote($$tree) ; _reset_sig_warn() ; return $return_val ; } elsif (ref($tree)) { my $k = $stat[4] ? $tag : &_check_key($tag) ; if ($stat[3] == 1) { $k = "\L$k\E" ;} elsif ($stat[3] == 2) { $k = "\U$k\E" ;} delete $$parsed{"$tree"} if ref($tree) ; my $return_val = " $k=" . &_add_quote("$tree") ; _reset_sig_warn() ; return $return_val ; } else { my $k = $stat[4] ? $tag : &_check_key($tag) ; if ($stat[3] == 1) { $k = "\L$k\E" ;} elsif ($stat[3] == 2) { $k = "\U$k\E" ;} delete $$parsed{"$tree"} if ref($tree) ; my $return_val = " $k=" . &_add_quote($tree) ; _reset_sig_warn() ; return $return_val ; } delete $$parsed{"$tree"} if ref($tree) ; _reset_sig_warn() ; return ; } ############## # _DATA_TYPE # ############## ## 4 binary ## 3 CDATA ## 2 content ## 1 value sub _data_type { &XML::Smart::_data_type ;} ############## # _CHECK_TAG # ############## sub _check_tag { &_check_key ;} ############## # _CHECK_KEY # ############## sub _check_key { _unset_sig_warn() ; if ($_[0] =~ /(?:^[.:-]|[^\w\:\.\-])/s) { my $k = $_[0] ; $k =~ s/^[.:-]+//s ; $k =~ s/[^\w\:\.\-]+/_/gs ; _reset_sig_warn() ; return( $k ) ; } my $return_val = $_[0] ; _reset_sig_warn() ; return( $return_val ) ; } ############## # _ADD_QUOTE # ############## sub _add_quote { _unset_sig_warn() ; my ($data) = @_ ; $data =~ s/\\$/\\\\/s ; &_add_basic_entity($data) ; my $q1 = ($data =~ /"/s) ? 1 : undef ; my $q2 = ($data =~ /'/s) ? 1 : undef ; if (!$q1 && !$q2) { _reset_sig_warn() ; return( qq`"$data"` ) ; } if ($q1 && $q2) { $data =~ s/"/"/gs ; _reset_sig_warn() ; return( qq`"$data"` ) ; } if ($q1) { _reset_sig_warn() ; return( qq`'$data'` ) ; } if ($q2) { _reset_sig_warn() ; return( qq`"$data"` ) ; } _reset_sig_warn() ; return( qq`"$data"` ) ; } ####### # END # ####### 1; XML-Smart-1.78/lib/XML/Smart.pm0000644000175000017500000017326312214354157015365 0ustar harishharish############################################################################# ## Name: Smart.pm ## Purpose: XML::Smart ## Author: Graciliano M. P. ## Modified by: Harish Madabushi ## Created: 10/05/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# package XML::Smart ; use 5.006 ; use strict ; use warnings ; use Carp ; use Object::MultiType ; use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; use vars qw(@ISA) ; @ISA = qw(Object::MultiType) ; use XML::Smart::Tie ; use XML::Smart::Tree ; =head1 NAME XML::Smart - A smart, easy and powerful way to access or create XML from fiels, data and URLs. =head1 VERSION Version 1.78 =cut our $VERSION = '1.78' ; =head1 SYNOPSIS This module provides an easy way to access/create XML data. It's based on a HASH tree created from the XML data, and enables dynamic access to it through the standard Perl syntax for Hash and Array, without necessarily caring about which you are working with. In other words, B! This module additionally provides special resources such as: search for nodes by attribute, select an attribute value in each multiple node, change the returned format, and so on. The module also automatically handles binary data (encoding/decoding to/from base64), CDATA (like contents with ) and Unicode. It can be used to create XML files, load XML from the Web ( just by using an URL as the file path ) and has an easy way to send XML data through sockets - just adding the length of the data in the header. You can use I with L, or with the 2 standard parsers of XML::Smart: =over 10 =item I =item I. =back I can be used to load/parse wild/bad XML data, or HTML tags. =head1 Tutorial and F.A.Q. You can find some extra documents about I at: =over 2 =item L - Tutorial and examples for XML::Smart. =item L - Frequently Asked Questions about XML::Smart. =back =cut =head1 USAGE ## Create the object and load the file: my $XML = XML::Smart->new('file.xml') ; ## Force the use of the parser 'XML::Smart::Parser'. my $XML = XML::Smart->new('file.xml' , 'XML::Smart::Parser') ; ## Get from the web: my $XML = XML::Smart->new('http://www.perlmonks.org/index.pl?node_id=16046') ; ## Cut the root: $XML = $XML->cut_root ; ## Or change the root: $XML = $XML->{hosts} ; ## Get the address [0] of server [0]: my $srv0_addr0 = $XML->{server}[0]{address}[0] ; ## ...or... my $srv0_addr0 = $XML->{server}{address} ; ## Get the server where the attibute 'type' eq 'suse': my $server = $XML->{server}('type','eq','suse') ; ## Get the address again: my $addr1 = $server->{address}[1] ; ## ...or... my $addr1 = $XML->{server}('type','eq','suse'){address}[1] ; ## Get all the addresses of a server: my @addrs = @{$XML->{server}{address}} ; ## ...or... my @addrs = $XML->{server}{address}('@') ; ## Get a list of types of all the servers: my @types = $XML->{server}('[@]','type') ; ## Add a new server node: my $newsrv = { os => 'Linux' , type => 'Mandrake' , version => 8.9 , address => [qw(192.168.3.201 192.168.3.202)] } ; push(@{$XML->{server}} , $newsrv) ; ## Get/rebuild the XML data: my $xmldata = $XML->data ; ## Save in some file: $XML->save('newfile.xml') ; ## Send through a socket: print $socket $XML->data(length => 1) ; ## show the 'length' in the XML header to the ## socket know the amount of data to read. __DATA__
192.168.0.1
192.168.0.2
192.168.1.10
192.168.1.20
=cut ############### # AUTOLOADERS # ############### ## Lead to mem leak? ## sub data { require XML::Smart::Data ; _unset_sig_warn() ; *data = \&XML::Smart::Data::data ; _reset_sig_warn() ; &XML::Smart::Data::data(@_) ; } sub apply_dtd { require XML::Smart::DTD ; _unset_sig_warn() ; *apply_dtd = \&XML::Smart::DTD::apply_dtd ; _reset_sig_warn() ; &XML::Smart::DTD::apply_dtd(@_) ; } sub xpath { _load_xpath() ; &XML::Smart::XPath::xpath(@_) ;} sub XPath { _load_xpath() ; &XML::Smart::XPath::XPath(@_) ;} sub xpath_pointer { _load_xpath() ; &XML::Smart::XPath::xpath_pointer(@_) ;} sub XPath_pointer { _load_xpath() ; &XML::Smart::XPath::XPath_pointer(@_) ;} sub _load_xpath { require XML::Smart::XPath ; _unset_sig_warn() ; *xpath = \&XML::Smart::XPath::xpath ; *XPath = \&XML::Smart::XPath::XPath ; *xpath_pointer = \&XML::Smart::XPath::xpath_pointer ; *XPath_pointer = \&XML::Smart::XPath::XPath_pointer ; *_load_xpath = sub {} ; _reset_sig_warn() ; } ################# # NO_XML_PARSER # ################# sub NO_XML_PARSER { $XML::Smart::Tree::NO_XML_PARSER = !@_ ? 1 : ( $_[0] ? 1 : undef ) ; } ####### # NEW # ####### sub new { my $class = shift ; my $file = shift ; my $parser = ($_[0] and $_[0] !~ /^(?:uper|low|arg|on|no|use)\w+$/i) ? shift(@_) : '' ; my $this = Object::MultiType->new( boolsub => \&boolean , scalarsub => \&content , tiearray => 'XML::Smart::Tie::Array' , tiehash => 'XML::Smart::Tie::Hash' , tieonuse => 1 , code => \&find_arg , ) ; $$this->{ parser } = $parser ; $parser = &XML::Smart::Tree::load($parser) ; if ( !($file) or $file eq '') { $$this->{tree} = {} ;} else { eval { $$this->{tree} = &XML::Smart::Tree::parse($file,$parser,@_) ; }; croak( $@ ) if( $@ ); } $$this->{point} = $$this->{tree} ; bless($this,$class) ; return $this ; } ######### # CLONE # ######### sub clone { my $saver = shift ; my ($pointer , $back , $array , $key , $i , $null_clone) ; if ($#_ == 0 && !ref $_[0]) { my $nullkey = shift ; $pointer = {} ; $back = {} ; $null_clone = 1 ; ($i) = ( $nullkey =~ /(?:^|\/)\/\[(\d+)\]$/s ); ($key) = ( $nullkey =~ /(.*?)(?:\/\/\[\d+\])?$/s ); if ($key =~ /^\/\[\d+\]$/) { $key = undef ;} } else { $pointer = shift ; $back = shift ; $array = shift ; $key = shift ; $i = shift ; } my $clone = Object::MultiType->new( boolsub => \&boolean , scalarsub => \&content , tiearray => 'XML::Smart::Tie::Array' , tiehash => 'XML::Smart::Tie::Hash' , tieonuse => 1 , code => \&find_arg , ) ; bless($clone,__PACKAGE__) ; if ( !$saver->is_saver ) { $saver = $$saver ;} if (!$back) { if (!$pointer) { $back = $saver->{back} ;} else { $back = $saver->{point} ;} } if (!$array && !$pointer) { $array = $saver->{array} ;} my @keyprev ; if (defined $key) { @keyprev = $key ;} elsif (defined $i) { @keyprev = "[$i]" ;} if (!defined $key) { $key = $saver->{key} ;} if (!defined $i) { $i = $saver->{i} ;} if (!$pointer) { $pointer = $saver->{point} ;} # my @call = caller ; # print STDERR "CLONE>> $key , $i >> @{$saver->{keyprev}} >> @_\n" ; $$clone->{tree} = $saver->{tree} ; $$clone->{point} = $pointer ; $$clone->{back} = $back ; $$clone->{array} = $array ; $$clone->{key} = $key ; $$clone->{i} = $i ; if ( @keyprev ) { $$clone->{keyprev} = ( $saver->{keyprev} ) ? [@{$saver->{keyprev}}] : [] ; push(@{$$clone->{keyprev}} , @keyprev) ; } if (defined $_[0]) { $$clone->{content} = \$_[0] ;} if ( $null_clone || $saver->{null} ) { $$clone->{null} = 1 ; ## $$clone->{self} = $clone ; } $$clone->{XPATH} = $saver->{XPATH} if $saver->{XPATH} ; return( $clone ) ; } ########### # BOOLEAN # ########### sub boolean { my $this = shift ; if ( $this->null ) { return 0 ; } else { return 1 ; } } ######## # NULL # ######## sub null { my $this = shift ; if( $$this->{null} ) { return 1 ; } if( (keys %{$$this->{tree}}) < 1 ) { return 1 ; } return ; } ######## # BASE # ######## sub base { my $this = shift ; my $base = Object::MultiType->new( boolsub => \&boolean , scalarsub => \&content , tiearray => 'XML::Smart::Tie::Array' , tiehash => 'XML::Smart::Tie::Hash' , tieonuse => 1 , code => \&find_arg , ) ; bless($base,__PACKAGE__) ; $$base->{tree} = $this->tree ; $$base->{point} = $$base->{tree} ; return( $base ) ; } ######## # BACK # ######## sub back { my $this = shift ; my @tree ; if( $$this->{keyprev} ) { @tree = @{$$this->{keyprev}} ; } if( !@tree ) { return $this ; } my $last = pop(@tree) ; my $i = 0 ; if( $last =~ /^\[(\d+)\]$/ ) { $i = $1 ; $last = pop(@tree) ; } my $back = $this->base ; foreach my $tree_i ( @tree ) { if ($tree_i =~ /^\[(\d+)\]$/) { my $i = $1 ; $back = $back->[$i] ; } else { $back = $back->{$tree_i} ; } } if ( wantarray ) { return( $back , $last , $i ) ; } return( $back ) ; } ######## # PATH # ######## sub path { my $this = shift ; my @tree = @{$$this->{keyprev}} ; my $path ; foreach my $tree_i ( @tree ) { $path .= '/' if $tree_i !~ /^\[\d+\]$/ ; $path .= $tree_i ; } return $path ; } ################# # PATH_AS_XPATH # ################# sub path_as_xpath { my $this = shift ; my @tree = @{$$this->{keyprev}} ; my $path ; foreach my $tree_i ( @tree ) { if ( $tree_i =~ /^\[(\d+)\]$/ ) { my $i = $1 + 1 ; $path .= "[$i]" ; } else { $path .= "/$tree_i" ; } } $path =~ s/\[1\]$// ; my $t = $this->is_node ; if ( !$this->is_node ) { $path =~ s/\/([^\/]+)$/\/\@$1/s ; } return $path ; } ######## # ROOT # ######## sub root { my $this = shift ; my $root = ( $this->base->nodes_keys )[0] ; return $root ; } ####### # KEY # ####### sub key { my $this = shift ; my $k = @{$$this->{keyprev}}[ $#{$$this->{keyprev}} ] ; if ($k =~ /^\[(\d+)\]$/) { $k = @{$$this->{keyprev}}[ $#{$$this->{keyprev}} -1 ] ; } return $k ; } ##### # I # ##### sub i { my $this = shift ; my $i = $$this->{i} ; return $i ; } ######## # COPY # ######## sub copy { my $this = shift ; my $data = $this->data( noheader => 1 ) ; my $copy = XML::Smart->new( $data, $$this->{ parser } ) ; if( $$this->{keyprev} ) { my @old_array = @{ $$this->{keyprev} } ; my @new_array = @old_array ; $$copy->{keyprev} = \@new_array ; } my ( $back , $key , $i ) = $copy->back ; _unset_sig_warn() ; if( $key ne '' ) { $copy = $back->{$key} ; $copy = $back->[$i] if $i ; } _reset_sig_warn() ; return $copy ; } ############## # _COPY_HASH # ############## sub _copy_hash { my ( $ref ) = @_ ; my $copy ; if( ref $ref eq 'HASH' ) { $copy = {} ; foreach my $Key ( keys %$ref ) { if( ref $$ref{$Key} ) { $$copy{$Key} =&_copy_hash($$ref{$Key}) ; } else { $$copy{$Key} = $$ref{$Key} ; } } } elsif( ref $ref eq 'ARRAY' ) { $copy = [] ; foreach my $i ( @$ref ) { if( ref $i ) { push( @$copy, &_copy_hash($i) ) ; } else { push( @$copy, $i ) ; } } } elsif( ref $ref eq 'SCALAR' ) { my $copy = $$ref ; return( \$copy ) ; } else { return( {} ) ; } return( $copy ) ; } ########### # TREE_OK # ########### sub tree_ok { return _tree_ok_parse( &tree ) ; } ############## # POINTER_OK # ############## sub pointer_ok { return _tree_ok_parse( &pointer ) ; } sub tree_pointer_ok { &pointer_ok ; } ################## # _TREE_OK_PARSE # ################## sub _tree_ok_parse { my ( $ref ) = @_ ; my $copy ; if( ref $ref eq 'HASH' ) { $copy = {} ; foreach my $Key ( keys %$ref ) { next if $Key eq '/order' || $Key eq '/nodes' || $Key =~ /\/\.CONTENT\// ; if( ref $$ref{$Key} ) { $$copy{$Key} =&_tree_ok_parse($$ref{$Key}) ; } else { $$copy{$Key} = $$ref{$Key} ; } } } elsif( ref $ref eq 'ARRAY' ) { $copy = [] ; foreach my $i ( @$ref ) { if( ref $i ) { push( @$copy, &_tree_ok_parse($i) ) ; } else { push( @$copy, $i ) ; } } } elsif( ref $ref eq 'SCALAR' ) { my $copy = $$ref ; return( \$copy ) ; } else { return( {} ) ; } return( $copy ) ; } ######## # TREE # ######## sub tree { my $hash_to_return = ${$_[0]}->{tree} ; return ( $hash_to_return ) ; } sub tree_pointer { &pointer ; } ############# # DUMP_TREE # ############# sub dump_tree { require Data::Dumper ; local $Data::Dumper::Sortkeys = 1 ; return Data::Dumper::Dumper( &tree ) ; } sub dump_tree_ok { require Data::Dumper ; local $Data::Dumper::Sortkeys = 1 ; return Data::Dumper::Dumper( &tree_ok ) ; } ################ # DUMP_POINTER # ################ sub dump_pointer { require Data::Dumper ; local $Data::Dumper::Sortkeys = 1 ; return Data::Dumper::Dumper( &pointer ) ; } sub dump_pointer_ok { require Data::Dumper ; local $Data::Dumper::Sortkeys = 1 ; return Data::Dumper::Dumper( &pointer_ok ) ; } sub dump_tree_pointer { &dump_pointer ; } sub dump_tree_pointer_ok { &dump_pointer_ok ; } ########### # POINTER # ########### sub pointer { my $hash_to_return ; if ( ${$_[0]}->{content} ) { $hash_to_return = ${${$_[0]}->{content}} ; } else { $hash_to_return = ${$_[0]}->{point} ; } return ( $hash_to_return ) ; } ############ # CUT_ROOT # ############ sub cut_root { my $this = shift ; my @nodes = $this->nodes_keys ; if( $#nodes > 0 ) { return $this ; } my $root = $nodes[0] ; return( $this->{$root} ) ; } ########### # IS_NODE # ########### sub is_node { my $this = shift ; return if $this->null ; my $key = $this->key ; my $back = $this->back ; return 1 if( $back->{'/nodes'}{$key} || $back->{$key}->nodes_keys ) ; return undef ; } ######## # ARGS # ######## sub args { my $this = shift ; return () if $this->null ; my @args ; my $nodes = $this->back->{'/nodes'} ; my $pointer = $$this->{point} ; foreach my $Key ( keys %$this ) { next if( $$nodes{$Key} ) ; if( ( !ref $$pointer{ $Key} ) || ( ref( $$pointer{ $Key} ) eq 'HASH') || ( ref( $$pointer{ $Key} ) eq 'ARRAY' && $#{$$pointer{$Key}} == 0 ) ) { push(@args , $Key) ; } } return @args ; } ############### # ARGS_VALUES # ############### sub args_values { my $this = shift ; return () if $this->null ; my @args = $this->args ; my @values ; foreach my $args_i ( @args ) { push( @values, $this->{$args_i} ) ; } return @values ; } ######### # NODES # ######### sub nodes { my $this = shift ; return () if $this->null ; my $nodes = $this->{'/nodes'}->pointer ; my $pointer = $$this->{point} ; my @nodes ; foreach my $Key ( keys %$this ) { if( $$nodes{$Key} || (ref($$pointer{$Key}) eq 'HASH') || (ref($$pointer{$Key}) eq 'ARRAY' && $#{$$pointer{$Key}} > 0) ) { if( ref($$pointer{$Key}) eq 'ARRAY' ) { my $n = $#{$$pointer{$Key}} ; for my $i (0..$n) { push( @nodes, $this->{$Key}[$i] ) ; } } else { push( @nodes, $this->{$Key}[0] ) ; } } } return @nodes ; } ############## # NODES_KEYS # ############## sub nodes_keys { my $this = shift ; return () if $this->null ; my $nodes = $this->{'/nodes'}->pointer ; my $pointer = $$this->{point} ; my @nodes ; foreach my $Key ( keys %$this ) { if( $$nodes{$Key} || (ref($$pointer{$Key}) eq 'HASH') || (ref($$pointer{$Key}) eq 'ARRAY' && $#{$$pointer{$Key}} > 0) ) { push(@nodes , $Key) ; } } return @nodes ; } ############ # SET_NODE # ############ sub set_node { my $this = shift ; my ( $bool ) = @_ ; if( !@_ ) { $bool = 1 ; } my $key = $this->key ; my $back = $this->back ; $back->{'/nodes'} = {} if( $back->{'/nodes'}->null ) ; my $nodes = $back->{'/nodes'}->pointer ; if( $bool ) { if( $$nodes{$key} && $$nodes{$key} =~ /^(\w+,\d+),(\d*)/ ) { $$nodes{$key} = "$1,1" ; } else { $$nodes{$key} = 1 ; } if ( !$this->{CONTENT} ) { my $content = $this->content ; $this->{CONTENT} = $content if $content ne '' ; } } else { delete $$nodes{$key} ; my @keys = keys %$this ; if( $#keys == 0 && $keys[0] eq 'CONTENT' ) { my $content = ( !$this->{CONTENT}->null ) ? $this->{CONTENT}('.') : $this->content ; $this->back->pointer->{$key} = $content ; } } } ########### # SET_TAG # ########### sub set_tag { &set_node ; } ############# # SET_ORDER # ############# sub set_order { my $this = shift ; my $pointer = $$this->{point} ; @{$$pointer{'/order'}} = @_ ; } sub order { my $this = shift ; my $pointer = $$this->{point} ; return @{$$pointer{'/order'}} if defined $$pointer{'/order'} && ref($$pointer{'/order'}) eq 'ARRAY' ; return() ; } ############# # SET_CDATA # ############# sub set_node_type { my $this = shift ; my ( $type, $bool ) = @_ ; if( $#_ < 1 ) { $bool = 1 ; } my $key = $this->key ; my $back = $this->back ; $back->{'/nodes'} = {} if( $back->{'/nodes'}->null ); my $nodes = $back->{'/nodes'}->pointer ; if( $bool ) { if( $$nodes{$key} && $$nodes{$key} =~ /^\w+,\d+,(\d*)/ ) { my $val = $1 ; $$nodes{$key} = "$type,1,$val" ; } else { my $existing_node_data = ( $$nodes{$key} ) ? $$nodes{$key} : "" ; $$nodes{$key} = "$type,1," . $existing_node_data ; } if( !$this->{CONTENT} ) { my $content = $this->content ; $this->{CONTENT} = $content if $content ne '' ; } } else { if( !$$nodes{$key} ) { my $tp = _data_type( $back->{$key} ) ; if ( $tp > 2 ) { $$nodes{$key} = "$type,0," ;} } elsif( $$nodes{$key} eq '1' ) { $$nodes{$key} = "$type,0,1" ; } elsif( $$nodes{$key} =~ /^\w+,\d+,1/ ) { $$nodes{$key} = "$type,0,1" ; } elsif( $$nodes{$key} =~ /^\w+,\d+,0?$/ ) { delete $$nodes{$key} ; my @keys = keys %$this ; if( $#keys == 0 && $keys[0] eq 'CONTENT') { my $content = $this->{CONTENT}('.') ; $this->back->pointer->{$key} = $content ; } } } } ############# # SET_CDATA # ############# sub set_cdata { my $this = shift ; $this->set_node_type('cdata',@_) ; } ############## # SET_BINARY # ############## sub set_binary { my $this = shift ; $this->set_node_type('binary',@_) ; } ################# # SET_AUTO_NODE # ################# sub set_auto_node { my $this = shift ; my $key = $this->key ; my $back = $this->back ; $back->{'/nodes'} = {} if( $back->{'/nodes'}->null ); my $nodes = $back->{'/nodes'}->pointer ; if( !$$nodes{$key} || $$nodes{$key} eq '1' ) { # Do nothing. ; } elsif( $$nodes{$key} =~ /^\w+,\d+,1/ ) { $$nodes{$key} = 1 ; } elsif( $$nodes{$key} =~ /^\w+,\d+,0?$/ ) { delete $$nodes{$key} ; my @keys = keys %$this ; if( $#keys == 0 && $keys[0] eq 'CONTENT') { my $content = $this->{CONTENT}('.') ; $this->back->pointer->{$key} = $content ; } } } ############ # SET_AUTO # ############ sub set_auto { my $this = shift ; my $key = $this->key ; my $back = $this->back ; $back->{'/nodes'} = {} if $back->{'/nodes'}->null ; my $nodes = $back->{'/nodes'}->pointer ; delete $$nodes{$key} ; my @keys = keys %$this ; if( $#keys == 0 && $keys[0] eq 'CONTENT') { my $content = $this->{CONTENT}('.') ; $this->back->pointer->{$key} = $content ; } } ############## # _DATA_TYPE # ############## ## 4 binary ## 3 CDATA ## 2 content ## 1 value sub _data_type { my $data = shift ; # TODO: 0x80, 0x81, 0x8d, 0x8f, 0x90, 0xa0 my @bin_data = ( 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8e, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9e, 0x9f, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x20, ); my $bin_string = join( '', ( map( pack("H*", $_), @bin_data ) ) ) ; return 4 if( $data && ( $data =~ /[^\w\d\s!"#\$\%&'\(\)\*\+,\-\.\/:;<=>\?\@\[\\\]\^\`\{\|}~~$bin_string]/s or $data =~ /(\240|\351|\361|\363|\341|\374|\340|\350|\366|\343|\355|\366|\344|\372|\364|\324|\301|\342)/s ) ) ; return 3 if( $data && $data =~ /<.*?>/s ) ; return 2 if( $data && $data =~ /[\r\n\t]/s ) ; return 1 ; } ####### # RET # ####### sub ret { my $this = shift ; my $type = shift ; if ($type =~ /^\s*\s*$/si ) { return $this->data_pointer( noheader => 1 ) ; } my @ret ; $type =~ s/[^<\$\@\%\.k]//gs ; if ($type =~ /^back ; if( $type =~ /\$$/ ) { @ret = $back->{$key}[$i]->content ; } elsif( $type =~ /\@$/ ) { @ret = @{$back} ; foreach my $ret_i ( @ret ) { $ret_i = $ret_i->{$key}[$i] ; } } elsif( $type =~ /\%$/ ) { @ret = %{$back->{$key}[$i]} ; } } else { if( $this->null ) { return ; } if ($type =~ /\$$/) { @ret = $this->content ; } elsif ($type =~ /\@$/) { @ret = @{$this} ; } elsif ($type =~ /\%$/) { @ret = %{$this} ; } elsif ($type =~ /\.$/) { @ret = $this->pointer ; } elsif ($type =~ /[\@\%]k$/) { my @keys = keys %{$this} ; foreach my $key ( @keys ) { my $n = $#{ $this->{$key} } ; if ($n > 0) { my @multi = ($key) x ($n+1) ; push(@ret , @multi) ; } else { push(@ret , $key) ; } } } } if( $type =~ /^\$./ ) { foreach my $ret_i ( @ret ) { if(ref($ret_i) eq 'XML::Smart') { $ret_i = $ret_i->content ; } } } if( wantarray ) { return( @ret ) ; } return $ret[0] ; } ######## # FIND # ######## sub find { &find_arg } ############ # FIND_ARG # ############ sub find_arg { my $this = shift ; if( $#_ == 0 && ref($_[0]) ne 'ARRAY' ) { return $this->ret(@_) ; } if( $#_ == 1 && $_[0] eq '[@]' ) { my $arg = $_[1] ; return $this->{$arg}('<@') ; } my @search ; for( my $i = 0; $i <= $#_ ; ++$i ) { if( ref($_[$i]) eq 'ARRAY' ) { push(@search , $_[$i]) ; } elsif( ref($_[$i]) ne 'ARRAY' && ref($_[$i+1]) ne 'ARRAY' && ref($_[$i+2]) ne 'ARRAY' ) { push(@search , [$_[$i] , $_[$i+1] , $_[$i+2]]) ; $i += 2 ; } } #use Data::Dumper ; print Dumper(\@search); #print "*** @search\n" ; if ( !@search ) { return ; } my $key = $$this->{key} ; my @hashes ; if( ref($$this->{array}) ) { push( @hashes, @{$$this->{array}} ) ; } else { push( @hashes, $$this->{point} ) ; if( ref $$this->{point} eq 'HASH' ) { foreach my $k ( sort keys %{$$this->{point}} ) { push( @hashes, [$k,$$this->{point}{$k}]) if( ref($$this->{point}{$k}) eq 'HASH' ) ; } } } my $i = -1 ; my (@hash , @i) ; my $notwant = !wantarray ; foreach my $hash_i ( @hashes ) { foreach my $search_i ( @search ) { my ($name , $type , $value) = @{$search_i} ; $type =~ s/\s//gs ; $i++ ; my $hash ; if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;} else { $hash = $hash_i ;} my $data ; if ($name =~ /^content$/i) { $name = 'CONTENT' ;} $data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ; $data = $$data{CONTENT} if ref($data) eq 'HASH' ; _unset_sig_warn() ; if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} _reset_sig_warn() ; } if( $notwant && @hash ) { last ; } } my $back = $$this->{back} ; #print "FIND>> @{$$this->{keyprev}} >> $i\n" ; if( @hash ) { if( $notwant ) { my ($k,$hash) = (undef) ; if (ref $hash[0] eq 'ARRAY') { ($k,$hash) = @{$hash[0]} ;} else { $hash = $hash[0] ;} return &XML::Smart::clone($this,$hash,$back,undef, $k,$i[0]) ; } else { my $c = -1 ; foreach my $hash_i ( @hash ) { $c++ ; my ($k,$hash) = (undef) ; if (ref $hash_i eq 'ARRAY') { ($k,$hash) = @{$hash_i} ;} else { $hash = $hash_i ;} $hash_i = &XML::Smart::clone($this,$hash,$back,undef, $k,$i[$c]) ; } return( @hash ) ; } } if (wantarray) { return() ;} return &XML::Smart::clone($this,'') ; } ########### # CONTENT # ########### sub content { my $this = shift ; my $set_i = $#_ > 0 ? shift : undef ; if ( $this->null ) { &XML::Smart::Tie::_generate_nulltree( $$this ) ; } ##use Data::Dumper; print Dumper($$this) ; my $content_to_return ; if ( defined $$this->{content} and ( !defined( $content_to_return ) ) ) { if (@_) { ${$$this->{content}} = $_[0] ;} $content_to_return = ${$$this->{content}} ; } my $key = 'CONTENT' ; my $i = $$this->{i} ; if( ( ref($$this->{point}) eq 'ARRAY' ) and ( !defined( $content_to_return ) ) ) { $content_to_return = $this->[0]->content($set_i,@_) ; } if( ( ref($$this->{point}) ne 'HASH' ) and ( !defined( $content_to_return ) ) ) { $content_to_return = '' ; } if( ( !exists $$this->{point}{$key} ) and ( !defined( $content_to_return ) ) ) { if( @_ ) { $content_to_return = $$this->{point}{$key} = $_[0] ; } else { $content_to_return = '' ; } } if( defined( $content_to_return ) ) { return $content_to_return ; } if( ( ref($$this->{point}{$key}) eq 'ARRAY' ) and ( !defined( $content_to_return ) ) ) { if($i eq '') { $i = 0 ; } if(@_) { $$this->{point}{$key}[$i] = $_[0] ; } $content_to_return = $$this->{point}{$key}[$i] ; } elsif( ( exists $$this->{point}{$key} ) and ( !defined( $content_to_return ) ) ) { if ( @_ ) { if ( my $tie = tied($$this->{point}{$key}) ) { $tie->STORE($set_i , $_[0]) ; } else { $$this->{point}{$key} = $_[0] ; } } if( wantarray && ( my $tie = tied($$this->{point}{$key} ) ) ) { my @tmp = $tie->FETCH(1) ; $content_to_return = \@tmp ; } else { $content_to_return = $$this->{point}{$key} ; } } unless( defined( $content_to_return ) ) { $content_to_return = '' ; } if( wantarray ) { return @{ $content_to_return } ; } else { return $content_to_return ; } } ######## # SAVE # ######## sub save { my $this = shift ; my $file = shift ; if(-d $file || (-e $file && !-w $file)) { return ; } my( $data, $unicode ) = $this->data(@_) ; my $fh ; open($fh,">$file") ; binmode($fh) if $unicode ; print $fh $data ; close($fh) ; return( 1 ) ; } ################ # DATA_POINTER # ################ sub data_pointer { my $this = shift ; if( $this->null ) { return ; } my( $point, $key ) ; if ( exists $$this->{content} ) { my $back = $this->back ; my $root = $back->key ; my $k = $this->key ; $point = $back->pointer ; $point = $$point{ $this->key } ; $point = {$root => {$k => $point} } ; } else { $point = $$this->{point} ; $key = $this->key ; } $this->data( tree => $point , root => $key , @_) ; } ########### # DESTROY # ########### sub DESTROY { my $this = shift ; if( $$this->{ DEV_DEBUG } ) { require Devel::Cycle ; my $circ_ref = 0 ; my $tmp = Devel::Cycle::find_cycle( $this, sub { my $path = shift; foreach (@$path) { my ($type,$index,$ref,$value) = @$_; $circ_ref = 1 ; } }); if( $circ_ref ) { $this->ANNIHILATE() ; my $tmp = Devel::Cycle::find_cycle( $this, sub { print STDERR "Circular reference found while destroying object - AFTER ANNIHILATE\n" ; }); } } $$this->clean if( $this && $$this ) ; # In case object was messed with ( bug 62091 ) } sub ANNIHILATE { my $this = shift ; my $base = shift ; if( ref $$this->{ point } eq 'HASH' ) { my %clean ; $$this->{ point } = \%clean ; } else { $this->{ point }->ANNIHILATE( ) ; } if( ref $$this->{ tree } eq 'HASH' ) { my %clean ; $$this->{ tree } = \%clean ; } else { $this->{ tree }->ANNIHILATE( ) ; } if( ref $$this->{ back } eq 'HASH' ) { my %clean ; $$this->{ back } = \%clean ; } else { $this->{ back }->ANNIHILATE( ) ; } if( $$this->{ XPATH } ) { # and ( ref $$this->{ XPATH } eq 'XML::XPath' ) ) { my $xpath = $$this->{ XPATH } ; $$xpath->cleanup() ; my $context = $$xpath->{ _context } ; my $context_ref = ref $context ; if( $context_ref =~ /XML\:\:XPath\:\:Node\:\:/ ) { _xml_xpath_clean( $context ) ; } } $$this->DESTROY(); return 1 ; } sub _xml_xpath_clean { my $path = shift ; $path->dispose() ; # Data::Structure::Util::unbless( $path ) ; return ; } ################### # STORABLE_FREEZE # ################### sub STORABLE_freeze { my $this = shift ; return($this , [$$this->{tree} , $$this->{pointer}]) ; } ################# # STORABLE_THAW # ################# sub STORABLE_thaw { my $this = shift ; $$this->{tree} = $_[1]->[0] ; $$this->{pointer} = $_[1]->[1] ; return ; } ####### # END # ####### 1; __END__ =head1 METHODS =head2 new (FILE|DATA|URL , PARSER , OPTIONS) Create a XML object. B =over 10 =item FILE|DATA|URL The first argument can be: - XML data as string. - File path. - File Handle (GLOB). - URL (Need LWP::UserAgent). If not passed, a null XML tree is started, where you should create your own XML data, than build/save/send it. =item PARSER B<(optional)> Set the XML parser to use. Options: XML::Parser XML::Smart::Parser XML::Smart::HTMLParser I can only handle basic XML data (not supported PCDATA, and any header like: ENTITY, NOTATION, etc...), but is a good choice when you don't want to install big modules to parse XML, since it comes with the main module. But it still can handle CDATA and binary data. ** See I<"PARSING HTML as XML"> for B. Aliases for the options: SMART|REGEXP => XML::Smart::Parser HTML => XML::Smart::HTMLParser I If not set it will look for XML::Parser and load it. If XML::Parser can't be loaded it will use XML::Smart::Parser, which is actually a clone of XML::Parser::Lite with some fixes. =item OPTIONS You can force the uper case and lower case for tags (nodes) and arguments (attributes), and other extra things. =over 10 =item lowtag Make the tags lower case. =item lowarg Make the arguments lower case. =item upertag Make the tags uper case. =item uperarg Make the arguments uper case. =item arg_single Set the value of arguments to 1 when they have a I value. I<** This option will work only when the XML is parsed by B, since it accept arguments without values:> my $xml = new XML::Smart( '' , 'XML::Smart::HTMLParser' , arg_single => 1 , ) ; In this example the option "arg_single" was used, what will define I to 1, but I will still have a null string value (""). Here's the tree of the example above: 'root' => { 'foo' => { 'flag' => 1, 'arg1' => '' }, }, =item use_spaces Accept contents that have only spaces. =item on_start (CODE) I<*optional> Code/sub to call on start a tag. I<** This will be called after XML::Smart parse the tag, should be used only if you want to change the tree.> =item on_char (CODE) I<*optional> Code/sub to call on content. I<** This will be called after XML::Smart parse the tag, should be used only if you want to change the tree.> =item on_end (CODE) I<*optional> Code/sub to call on end a tag. I<** This will be called after XML::Smart parse the tag, should be used only if you want to change the tree.> =back I<** This options are applied when the XML data is loaded. For XML generation see data() OPTIONS.> =back B my $xml_from_url = XML::Smart->new("http://www.perlmonks.org/index.pl?node_id=16046") ; ... my $xml_from_str = XML::Smart->new(q` `) ; ... my $null_xml = XML::Smart->new() ; ... my $xml_from_html = XML::Smart->new($html_data , 'html' , lowtag => 1 , lowarg => 1 , on_char => sub { my ( $tag , $pointer , $pointer_back , $cont) = @_ ; $pointer->{extra_arg} = 123 ; ## add an extrar argument. $pointer_back->{$tag}{extra_arg} = 123 ; ## Same, but using the previous pointer. $$cont .= "\n" ; ## append data to the content. } ) ; =head2 apply_dtd (DTD , OPTIONS) Apply the I to the XML tree. I can be a source, file, GLOB or URL. This method is usefull if you need to have the XML generated by I formated in a specific DTD, so, elements will be nodes automatically, attributes will be checked, required elements and attributes will be created, the element order will be set, etc... B =over 10 =item no_delete BOOL If TRUE tells that not defined elements and attributes in the DTD won't be deleted from the XML tree. =back B $xml->apply_dtd(q` ]> ` , no_delete => 1 , ); =head2 args() Return the arguments names (not nodes). =head2 args_values() Return the arguments values (not nodes). =head2 back() Get back one level the pointer in the tree. ** Se I. =head2 base() Get back to the base of the tree. Each query to the XML::Smart object return an object pointing to a different place in the tree (and share the same HASH tree). So, you can get the main object again (an object that points to the base): my $srv = $XML->{root}{host}{server} ; my $addr = $srv->{adress} ; my $XML2 = $srv->base() ; $XML2->{root}{hosts}... =head2 content() Return the content of a node: ## Data: my content ## Access: my $content = $XML->{foo}->content ; print "<<$content>>\n" ; ## show: <> ## or just: my $content = $XML->{foo} ; B For this XML data: content0 content1 Getting all the content: my $all_content = $XML->{root}->content ; print "[$all_content]\n" ; Output: [ content0 content1 ] Getting in parts: my @contents = $XML->{root}->content ; print "[@contents[0]]\n" ; print "[@contents[1]]\n" ; Output [ content0 ] [ content1 ] B $XML->{root}->content(0,"aaaaa") ; $XML->{root}->content(1,"bbbbb") ; Output now will be: [aaaaa] [bbbbb] And now the XML data generated will be: aaaaabbbbb =head2 copy() Return a copy of the XML::Smart object (pointing to the base). ** This is good when you want to keep 2 versions of the same XML tree in the memory, since one object can't change the tree of the other! B set_node(), set_cdata() and set_binary() changes are not persistant over copy - Once you create a second copy these states are lost. b do not copy after apply_dtd() unless you have checked for dtd errors. =head2 cut_root() Cut the root key: my $srv = $XML->{rootx}{host}{server} ; ## Or if you don't know the root name: $XML = $XML->cut_root() ; my $srv = $XML->{host}{server} ; ** Note that this will cut the root of the pointer in the tree. So, if you are in some place that have more than one key (multiple roots), the same object will be retuned without cut anything. =head2 data (OPTIONS) Return the data of the XML object (rebuilding it). B =over 11 =item nodtd Do not add in the XML content the DTD applied by the method I. =item noident If set to true the data isn't idented. =item nospace If set to true the data isn't idented and doesn't have space between the tags (unless the CONTENT have). =item lowtag Make the tags lower case. =item lowarg Make the arguments lower case. =item upertag Make the tags uper case. =item uperarg Make the arguments uper case. =item length If set true, add the attribute 'length' with the size of the data to the xml header (). This is useful when you send the data through a socket, since the socket can know the total amount of data to read. =item noheader Do not add the header. =item nometagen Do not add the meta generator tag: =item meta Set the meta tags of the XML document. =item decode As of VERSION 1.73 there are three different base64 encodings that are used. They are picked based on which of them support the data provided. If you want to retrieve data using the 'data' function the resultant xml will have dt:dt="binary.based" contained within it. To retrieve the decoded data use: $XML->data( decode => 1 ) Examples: my $meta = { build_from => "wxWindows 2.4.0" , file => "wx26.htm" , } ; print $XML->data( meta => $meta ) ; __DATA__ Multiple meta: my $meta = [ {build_from => "wxWindows 2.4.0" , file => "wx26.htm" } , {script => "genxml.pl" , ver => "1.0" } , ] ; __DATA__ Or set directly the meta tag: my $meta = '' ; ## For multiple: my $meta = ['' , ''] ; print $XML->data( meta => $meta ) ; =item tree Set the HASH tree to parse. If not set will use the tree of the XML::Smart object (I). ; =item wild Accept wild tags and arguments. ** This wont fix wrong keys and tags. =item sortall Sort all the tags alphabetically. If not set will keep the order of the document loaded, or the order of tag creation. I off =back =head2 data_pointer (OPTIONS) Make the tree from current point in the XML tree (not from the base as data()). Accept the same OPTIONS of the method B>. =head2 dump_tree() Dump the tree of the object using L. =head2 dump_tree_pointer() Dump the tree of the object, from the pointer, using L. =head2 dump_pointer() I<** Same as dump_tree_pointer()>. =head2 i() Return the index of the value. ** If the value is from an hash key (not an ARRAY ref) undef is returned. =head2 is_node() Return if a key is a node. =head2 key() Return the key of the value. If wantarray return the index too: return(KEY , I) ; =head2 nodes() Return the nodes (objects) in the pointer (keys that aren't arguments). =head2 nodes_keys() Return the nodes names (not the object) in the pointer (keys that aren't arguments). =head2 null() Return I if the XML object has a null tree or if the pointer is in some place that doesn't exist. =head2 order() Return the order of the keys. See I. =head2 path() Return the path of the pointer. I: /hosts/server[1]/address[0] B B<** See I.> =head2 path_as_xpath() Return the path of the pointer in the XPath format. =head2 pointer Return the HASH tree from the pointer. =head2 pointer_ok Return a copy of the tree of the object, B, but without internal keys added by I. =head2 root Return the ROOT name of the XML tree (main key). ** See also I for sub nodes. =head2 save (FILEPATH , OPTIONS) Save the XML data inside a file. Accept the same OPTIONS of the method B>. =head2 set_auto Define the key to be handled automatically. Soo, data() will define automatically if it's a node, content or attribute. I<** This method is useful to remove set_node(), set_cdata() and set_binary() changes.> =head2 set_auto_node Define the key as a node, and data() will define automatically if it's CDATA or BINARY. I<** This method is useful to remove set_cdata() and set_binary() changes.> =head2 set_binary(BOOL) Define the node as a BINARY content when TRUE, or force to B handle it as a BINARY on FALSE. Example of node handled as BINARY: PGgxPnRlc3QgAzwvaDE+ Original content of foo (the base64 data):

test \x03

=head2 set_cdata(BOOL) Define the node as CDATA when TRUE, or force to B handle it as CDATA on FALSE. Example of CDATA node: bla bla]]> =head2 set_node(BOOL) Set/unset the current key as a node (tag). ** If BOOL is not defined will use I. B You cannot set_node, copy the object and then set_node( 0 ) [ Unset node ] =head2 set_order(KEYS) Set the order of the keys (nodes and attributes) in this point. =head2 set_tag Same as set_node. =head2 tree() Return the HASH tree of the XML data. ** Note that the real HASH tree is returned here. All the other ways return an object that works like a HASH/ARRAY through tie. =head2 tree_pointer() Same as I. =head2 tree_ok() Return a copy of the tree of the object, but without internal keys added by I, like I and I. =head2 tree_pointer_ok() Return a copy of the tree of the object, B, but without internal keys added by I. =head2 xpath() || XPath() Return a XML::XPath object, based in the XML root in the tree. ## look from the root: my $data = $XML->XPath->findnodes_as_string('/') ; I<** Need XML::XPath installed, but only load when is needed.> =head2 xpath_pointer() || XPath_pointer() Return a XML::XPath object, based in the XML::Smart pointer in the tree. ## look from this point, soo XPath '/' actually starts at /server/: my $srvs = $XML->{server} ; my $data = $srvs->XPath_pointer->findnodes_as_string('/') ; I<** Need XML::XPath installed, but only load when is needed.> =head2 ANNIHILATE XML::Smart uses XML::XPath that, for perfomance reasons, leaks memory. The ensure that this memory is freed you can explicitly call ANNIHILATE before the XML::Smart object goes out of scope. =head1 ACCESS To access the data you use the object in a way similar to HASH and ARRAY: my $XML = XML::Smart->new('file.xml') ; my $server = $XML->{server} ; But when you get a key {server}, you are actually accessing the data through tie(), not directly to the HASH tree inside the object, (This will fix wrong accesses): ## {server} is a normal key, not an ARRAY ref: my $server = $XML->{server}[0] ; ## return $XML->{server} my $server = $XML->{server}[1] ; ## return UNDEF ## {server} has an ARRAY with 2 items: my $server = $XML->{server} ; ## return $XML->{server}[0] my $server = $XML->{server}[0] ; ## return $XML->{server}[0] my $server = $XML->{server}[1] ; ## return $XML->{server}[1] To get all the values of multiple elements/keys: ## This work having only a string inside {address}, or with an ARRAY ref: my @addrsses = @{$XML->{server}{address}} ; =head2 Select search When you don't know the position of the nodes, you can select it by some attribute value: my $server = $XML->{server}('type','eq','suse') ; ## return $XML->{server}[1] Syntax for the select search: (NAME, CONDITION , VALUE) =over 10 =item NAME The attribute name in the node (tag). =item CONDITION Can be eq ne == != <= >= < > For REGEX: =~ !~ ## Case insensitive: =~i !~i =item VALUE The value. For REGEX use like this: $XML->{server}('type','=~','^s\w+$') ; =back =head2 Select attributes in multiple nodes: You can get the list of values of an attribute looking in all multiple nodes: ## Get all the server types: my @types = $XML->{server}('[@]','type') ; Also as: my @types = $XML->{server}{type}('<@') ; Without the resource: my @list ; my @servers = @{$XML->{server}} ; foreach my $servers_i ( @servers ) { push(@list , $servers_i->{type} ) ; } =head2 Return format You can change the returned format: Syntax: (TYPE) Where TYPE can be: $ ## the content. @ ## an array (list of multiple values). % ## a hash. . ## The exact point in the tree, not an object. $@ ## an array, but with the content, not an objects. $% ## a hash, but the values are the content, not an object. ## The use of $@ and $% is good if you don't want to keep the object ## reference (and save memory). @keys ## The keys of the node. note that if you have a key with ## multiple nodes, it will be replicated (this is the ## difference of "keys %{$this->{node}}" ). <@ ## Return the attribute in the previous node, but looking for ## multiple nodes. Example: my @names = $this->{method}{wxFrame}{arg}{name}('<@') ; #### @names = (parent , id , title) ; ## Return a XML data from this point. __DATA__ Example: ## A servers content my $name = $XML->{server}{name}('$') ; ## ... or: my $name = $XML->{server}{name}->content ; ## ... or: my $name = $XML->{server}{name} ; $name = "$name" ; ## All the servers my @servers = $XML->{server}('@') ; ## ... or: my @servers = @{$XML->{server}} ; ## It still has the object reference: @servers[0]->{name} ; ## Without the reference: my @servers = $XML->{server}('$@') ; ## A XML data, same as data_pointer(): my $xml_data = $XML->{server}('') ; =head2 CONTENT If a {key} has a content you can access it directly from the variable or from the method: my $server = $XML->{server} ; print "Content: $server\n" ; ## ...or... print "Content: ". $server->content ."\n" ; So, if you use the object as a string it works as a string, if you use as an object it works as an object! ;-P I<**See the method content() for more.> =head1 CREATING XML DATA To create XML data is easy, you just use as a normal HASH, but you don't need to care with multiple nodes, and ARRAY creation/convertion! ## Create a null XML object: my $XML = XML::Smart->new() ; ## Add a server to the list: $XML->{server} = { os => 'Linux' , type => 'mandrake' , version => 8.9 , address => '192.168.3.201' , } ; ## The data now: ## Add a new address to the server. Have an ARRAY creation, convertion ## of the previous key to ARRAY: $XML->{server}{address}[1] = '192.168.3.202' ; ## The data now:
192.168.3.201
192.168.3.202
After create your XML tree you just save it or get the data: ## Get the data: my $data = $XML->data ; ## Or save it directly: $XML->save('newfile.xml') ; ## Or send to a socket: print $socket $XML->data(length => 1) ; =head1 BINARY DATA & CDATA From version 1.2 I can handle binary data and CDATA blocks automatically. B, binary data will be detected as: f1NPTUUgQklOQVJZIERBVEE= I.> The content will be decoded from base64 and saved in the object tree. CDATA will be parsed as any other content, since CDATA is only a block that won't be parsed. B, like at $XML->data(), the binary format and CDATA are detected using these rules: BINARY: - If your data has characters that can't be in XML. * Characters accepted: \s \w \d !"#$%&'()*+,-./:;<=>?@[\]^`{|}~ 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8e, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9e, 0x9f, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x20 TODO: 0x80, 0x81, 0x8d, 0x8f, 0x90, 0xa0 CDATA: - If have tags: <...> CONTENT: (content) - If have \r\n\t, or ' and " at the same time. So, this will be a CDATA content: line2 ]]> If binary content is detected, it will be converted to B and a B attribute added in the tag to tell the format. f1NPTUUgQklOQVJZIERBVEE= B As of VERSION 1.73 there are three different base64 encodings that are used. They are picked based on which of them support the data provided. If you want to retrieve data using the 'data' function the resultant xml will have dt:dt="binary.based" contained within it. To retrieve the decoded data use: $XML->data( decode => 1 ) =head1 UNICODE and ASCII-extended (ISO-8859-1) I support only thse 2 encode types, Unicode (UTF-8) and ASCII-extended (ISO-8859-1), and must be enough. (B). When creating XML data, if any UTF-8 character is detected the I attribute in the header will be set to UTF-8: 0x82, 0x83 If not, the I is used: 0x82 When loading XML data with UTF-8, Perl (5.8+) should make all the work internally. =head1 PARSING HTML as XML, or BAD XML formats You can use the special parser B to "use" HTML as XML or not well-formed XML data. The differences between an normal XML parser and I are: - Accept values without quotes: - Accept any data in the values, including <> and &: out.txt"> - Accpet URI values without quotes: - Don't need to close the tags adding the '/' before '>': ** Note that the parse will try hard to detect the nodes, and where auto-close or not. - Don't need to have only one root: datadata So, I is a willd way to load markuped data (like HTML), or if you don't want to care with quotes, end tags, etc... when writing by hand your XML data. So, you can write by hand a bad XML file, load it with I, and B saving it again! ;-P ** Note that =head1 ENTITIES Entities (ENTITY) are handled by the parser. So, if you use L it will do all the job fine. But If you use I or I, only the basic entities (defaults) will be parsed: < => The less than sign (<). > => The greater than sign (>). & => The ampersand (&). ' => The single quote or apostrophe ('). " => The double quote ("). &#ddd; => An ASCII character or an Unicode character (>255). Where ddd is a decimal. &#xHHH; => An Unicode character. Where HHH is in hexadecimal. B, already existent Entities won't be changed, and the characters '<', '&' and '>' will be converted to the appropriated entity. ** Note that if a content have a , the characters '<' and '>' won't be converted to entities, and this content will be inside a CDATA block. =head1 WHY AND HOW IT WORKS Every one that have tried to use Perl HASH and ARRAY to access XML data, like in L, have some problems to add new nodes, or to access the node when the user doesn't know if it's inside an ARRAY, a HASH or a HASH key. I create around it a very dynamic way to access the data, since at the same time any node/point in the tree can be a HASH and an ARRAY. You also have other extra resources, like a search for nodes by attribute: my $server = $XML->{server}('type','eq','suse') ; ## This syntax is not wrong! ;-) ## Instead of: my $server = $XML->{server}[1] ; __DATA__ The idea for this module, came from the problem that exists to access a complex struture in XML. You just need to know how is this structure, something that is generally made looking the XML file (what is wrong). But at the same time is hard to always check (by code) the struture, before access it. XML is a good and easy format to declare your data, but to extrac it in a tree way, at least in my opinion, isn't easy. To fix that, came to my mind a way to access the data with some query language, like SQL. The first idea was to access using something like: XML.foo.bar.baz{arg1} X = XML.foo.bar* X.baz{arg1} XML.hosts.server[0]{argx} And saw that this is very similar to Hashes and Arrays in Perl: $XML->{foo}{bar}{baz}{arg1} ; $X = $XML->{foo}{bar} ; $X->{baz}{arg1} ; $XML->{hosts}{server}[0]{argx} ; But the problem of Hash and Array, is not knowing when you have an Array reference or not. For example, in XML::Simple: ## This is very diffenrent $XML->{server}{address} ; ## ... of this: $XML->{server}{address}[0] ; So, why don't make both ways work? Because you need to make something crazy! To create I, first I have created the module L. With it you can have an object that works at the same time as a HASH, ARRAY, SCALAR, CODE & GLOB. So you can do things like this with the same object: $obj = Object::MultiType->new() ; $obj->{key} ; $obj->[0] ; $obj->method ; @l = @{$obj} ; %h = %{$obj} ; &$obj(args) ; print $obj "send data\n" ; Seems to be crazy, and can be more if you use tie() inside it, and this is what I does. For I, the access in the Hash and Array way paste through tie(). In other words, you have a tied HASH and tied ARRAY inside it. This tied Hash and Array work together, soo B: %hash = ( key => ['a','b','c'] ) ; $hash->{key} ## return $hash{key}[0] $hash->{key}[0] ## return $hash{key}[0] $hash->{key}[1] ## return $hash{key}[1] ## Inverse: %hash = ( key => 'a' ) ; $hash->{key} ## return $hash{key} $hash->{key}[0] ## return $hash{key} $hash->{key}[1] ## return undef The best thing of this new resource is to avoid wrong access to the data and warnings when you try to access a Hash having an Array (and the inverse). Thing that generally make the script die(). Once having an easy access to the data, you can use the same resource to B data! For example: ## Previous data: ## Now you have {address} as a normal key with a string inside: $XML->{hosts}{server}{address} ## And to add a new address, the key {address} need to be an ARRAY ref! ## So, XML::Smart make the convertion: ;-P $XML->{hosts}{server}{address}[1] = '192.168.2.101' ; ## Adding to a list that you don't know the size: push(@{$XML->{hosts}{server}{address}} , '192.168.2.102') ; ## The data now:
192.168.2.100
192.168.2.101
192.168.2.102
Than after changing your XML tree using the Hash and Array resources you just get the data remade (through the Hash tree inside the object): my $xmldata = $XML->data ; B always return an object>! Even when you get a final key. So this actually returns another object, pointhing (inside it) to the key: $addr = $XML->{hosts}{server}{address}[0] ; ## Since $addr is an object you can TRY to access more data: $addr->{foo}{bar} ; ## This doens't make warnings! just return UNDEF. ## But you can use it like a normal SCALAR too: print "$addr\n" ; $addr .= ':80' ; ## After this $addr isn't an object any more, just a SCALAR! =head1 TODO * Finish XPath implementation. * DTD - Handle gracefully. * Implement a better way to declare meta tags. * Add 0x80, 0x81, 0x8d, 0x8f, 0x90, 0xa0 ( multi byte characters to the list of accepted binary characters ) * Ensure object copy holds more in state including: ->data( wild => 1 ) =head1 SEE ALSO L, L, L, L. L - This is the module that make everything possible, and was created specially for I. ;-P ** See the test.pl script for examples of use. L =head1 AUTHOR Graciliano M. P. C<< >> I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P =head1 CURRENT MAINTAINER Harish Madabushi, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. Both the author and the maintainer will be notified, and then you'll automatically be notified of progress on your bug as changes are made. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc XML::Smart You can also look for information at: =over 5 =item * RT: CPAN's request tracker (report bugs here) L =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * Search CPAN L =item * GitHub CPAN L =back =head1 THANKS Thanks to Rusty Allen for the extensive tests of CDATA and BINARY handling of XML::Smart. Thanks to Ted Haining to point a Perl-5.8.0 bug for tied keys of a HASH. Thanks to everybody that have sent ideas, patches or pointed bugs. =head1 LICENSE AND COPYRIGHT Copyright 2003 Graciliano M. P. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut