Module: @QName: MDOM|TreeStore @enFN: DOM Tree Store Module @enDesc: The manakai DOM Tree Store Module provides a simple storable representation of a DOM subtree. @Namespace: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/TreeStore/ @DISCore:author: DISCore|Wakaba @License: license|Perl+MPL @Date: $Date: 2006/12/30 13:25:33 $ @Require: @@Module: @@@QName: MDOM|TreeCore Namespace: @c: http://suika.fam.cx/~wakaba/archive/2004/8/18/dom-core# @cfg: http://suika.fam.cx/www/2006/dom-config/ @dis: http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-- @doc: http://suika.fam.cx/~wakaba/archive/2005/7/tutorial# @d: http://suika.fam.cx/~wakaba/archive/2004/dom/xdt# @DOMMain: http://suika.fam.cx/~wakaba/archive/2004/dom/main# @domperl: http://suika.fam.cx/~wakaba/archive/2006/dom/perl/ @dx: http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException# @dxm: http://suika.fam.cx/~wakaba/archive/2004/dis/XML# @ecore: http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/ @ev: http://www.w3.org/2001/xml-events @f: http://suika.fam.cx/~wakaba/archive/2004/dom/feature# @fe: http://suika.fam.cx/www/2006/feature/ @idl: http://suika.fam.cx/~wakaba/archive/2004/dis/IDL# @infoset: http://www.w3.org/2001/04/infoset# @kwd: http://suika.fam.cx/~wakaba/archive/2005/rfc2119/ @lang: http://suika.fam.cx/~wakaba/archive/2004/8/18/lang# @license: http://suika.fam.cx/~wakaba/archive/2004/8/18/license# @ManakaiDOM: http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom# @MDOM: http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#ManakaiDOM. @MDOMX: http://suika.fam.cx/~wakaba/archive/2004/8/4/manakai-dom-exception# @null: http://suika.fam.cx/~wakaba/-temp/2003/09/27/null @rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# @t: http://suika.fam.cx/~wakaba/archive/2004/dom/tree# @tc: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/TreeCore/ @td: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/Document/ @te: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/Element/ @test: http://suika.fam.cx/~wakaba/archive/2004/dis/Test# @tst: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/TreeStore/ @tx: http://suika.fam.cx/~wakaba/archive/2005/manakai/DOM/XML/ @urigen: http://suika.fam.cx/~wakaba/archive/2005/manakai/URI/Generic/ @Util: http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/ @xml: http://www.w3.org/XML/1998/namespace @xml-dtd: http://www.w3.org/TR/REC-xml @xmlns: http://www.w3.org/2000/xmlns/ ElementTypeBinding: @Name: CODE @ElementType: dis:ResourceDef @ShadowContent: @@DISCore:resourceType: DISPerl|BlockCode @@ForCheck: ManakaiDOM|ForClass ElementTypeBinding: @Name: Method @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: DISLang|Method ElementTypeBinding: @Name: Param @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: DISLang|MethodParameter ElementTypeBinding: @Name: Return @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: DISLang|MethodReturn ElementTypeBinding: @Name: nullCase @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: ManakaiDOM:InCase @@Value: @@@is-null:1 ElementTypeBinding: @Name: IFQName @ElementType: dis:QName @ShadowContent: @@ForCheck: ManakaiDOM|ForIF ElementTypeBinding: @Name: ClsQName @ElementType: dis:QName @ShadowContent: @@ForCheck: ManakaiDOM|ForClass ## -- Features ElementTypeBinding: @Name: FeatureDef @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: f|Feature ElementTypeBinding: @Name: FeatureVerDef @ElementType: dis:ResourceDef @ShadowContent: @@rdf:type: f|Feature ElementTypeBinding: @Name: featureQName @ElementType: f:name @ShadowContent: @@ContentType: DISCore|QName FeatureDef: @QName: TSFeature @featureQName: fe|TreeStore @FeatureVerDef: @@QName: TSFeature30 @@f:instanceOf: d|Feature @@f:version: 3.0 @@f:requires: c|CoreFeature30 @@f:requires: tx|XMLFeature30 ElementTypeBinding: @Name: IFClsDef @ElementType: dis:ResourceDef @ShadowContent: @@DISCore:resourceType: @@@@: dis|MultipleResource @@@ForCheck: !ManakaiDOM|ForIF !ManakaiDOM|ForClass @@resourceFor: ManakaiDOM|ForIF @@resourceFor: @@@@: ManakaiDOM|ForClass @@DISCore:resourceType: @@@@: DISLang|Interface @@@ForCheck: ManakaiDOM|ForIF @@DISCore:resourceType: @@@@: DISLang|Class @@@ForCheck: ManakaiDOM|ForClass @@Implement: @@@@: ||+||ManakaiDOM|ForIF @@@ContentType: DISCore|TFPQNames @@@ForCheck: ManakaiDOM|ForClass ElementTypeBinding: @Name: Test @ElementType: dis:ResourceDef @ShadowContent: @@DISCore:resourceType: test|StandaloneTest @@ForCheck: ManakaiDOM|ForClass ## -- Implementation IFClsDef: @IFQName: DOMImplementationTreeStore @ClsQName: ManakaiDOMImplementationTreeStore @domperl:implementedByObjectsOf: c|DOMImplementation @domperl:classImplementedByObjectsOf: c|ManakaiDOMImplementation @f:implements: TSFeature30 @Test: @@QName: DOMImplementationTreeStore.interface.1.test @@PerlDef: $test->assert_true (->isa ()); @Test: @@QName: DOMImplementationTreeStore.class.1.test @@PerlDef: $test->assert_true (->isa ()); @Test: @@QName: ImplementationRegistry.getImplementation.1.test @@PerlDef: my $impl = $Message::DOM::ImplementationRegistry ->get_dom_implementation ({ => '3.0'}); $test->id ('DOMImplementationTreeStore'); $test->assert_isa ($impl, ); $test->id ('DOMImplementationTree'); $test->assert_isa ($impl, ); @Test: @@QName: ImplementationRegistry.getImplementation.2.test @@PerlDef: my $impl = $Message::DOM::ImplementationRegistry ->get_dom_implementation ({ => '3.0', Core => '3.0'}); $test->id ('DOMImplementationTreeStore'); $test->assert_isa ($impl, ); $test->id ('DOMImplementationTree'); $test->assert_isa ($impl, ); @Test: @@QName: DOMImplementation.getFeature.1.test @@PerlDef: my $impl; __CODE{tc|createImplForTest:: $impl => $impl}__; my $gf = $impl->get_feature ( => '3.0'); $test->id ('DOMImplementationTreeStore'); $test->assert_isa ($gf, ); $test->id ('DOMImplementationTree'); $test->assert_isa ($gf, ); @CODE: @@QName: tst|createImplForTest @@PerlDef: $impl = ->_new; @Method: @@Name: createStorableObjectFromNode @@enDesc: Creates a storable representation of the and its subtree. @@Param: @@@Name: in @@@Type: tc|Node @@@enDesc: The original to convert. @@Return: @@@Type: StorableObject @@@enDesc: A storable representation of the node. @@@dx:raises: @@@@@: c|CLONE_NODE_TYPE_NOT_SUPPORTED_ERR @@@@enDesc: If the node is of type other than , , , , , or . @@@PerlDef: if ({ => true, => true, => true, => true, => true, => true, }->{$in->}) { my @target = ([$in, # node null]); # origin while (@target) { my $target = shift @target; my $tnt = $target->[0]->; if ($tnt == ) { my $v = {}; my $pv = ${$target->[0]}->{}; $v->{namespace_uri} = $pv if defined $pv; $pv = ${$target->[0]}->{}; $v->{local_name} = $pv; $pv = ${$target->[0]}->{}; $v->{prefix} = $pv if defined $pv; for (@{$target->[0]->}) { push @target, [$_, $v]; } for (@{$target->[0]->}) { push @target, [$_, $v]; } if (defined $target->[1]) { push @{$target->[1]->{child_nodes} ||= []}, $v; } else { $r = $v unless defined $r; } } elsif ($tnt == ) { my $v = { value => \ $target->[0]->, }; my $pv = ${$target->[0]}->{}; $v->{namespace_uri} = $pv if defined $pv; $pv = ${$target->[0]}->{}; $v->{local_name} = $pv; $pv = ${$target->[0]}->{}; $v->{prefix} = $pv if defined $pv; if (defined $target->[1]) { push @{$target->[1]->{attributes} ||= []}, $v; } else { $r = $v unless defined $r; } } elsif ($tnt == or $tnt == ) { my $v = {}; $v->{data} = ${$target->[0]}->{}; if (defined $target->[1]) { push @{$target->[1]->{child_nodes} ||= []}, $v; } else { $r = $v unless defined $r; } } elsif ($tnt == ) { my $v = { xml_version => $target->[0]->, }; for (@{$target->[0]->}) { push @target, [$_, $v]; } $r = $v unless defined $r; } elsif ($tnt == ) { my $v = {}; for (@{$target->[0]->}) { push @target, [$_, $v]; } $r = $v unless defined $r; } elsif ($tnt == ) { for (@{$target->[0]->}) { push @target, [$_, $target->[1]]; } } } } else { __EXCEPTION{c|CLONE_NODE_TYPE_NOT_SUPPORTED_ERR:: MDOMX|param-name => 'in', c|node => {$in}, }__; } @Method: @@Name: createNodeFromStorableObject @@enDesc: Creates a and its subtree from a storable representation. @@Param: @@@Name: in @@@Type: StorableObject @@@enDesc: The original node storable representation to convert. @@Param: @@@Name: od @@@Type: td|Document @@@enDesc: The owner document to which the generated nodes belong. If the top-level object represents a document, this parameter be ignored. @@@nullCase: @@@@enDesc: A new empty is created. If the top-level object represents a document, the created be modified so that it represents that document. @@Return: @@@Type: tc|Node @@@enDesc: A created from the top-level object. @@@PerlDef: __DEEP{ $od = $self->; my $orig_strict = $od->; $od-> (false); my @target = ([$in, null, # parent node null]); # owner element while (@target) { my $target = shift @target; if (defined $target->[0]->{local_name}) { if (defined $target->[0]->{value}) { # Attribute my $node = $od-> ($target->[0]->{namespace_uri}, [$target->[0]->{prefix}, $target->[0]->{local_name}]); $node-> ($target->[0]->{value}); if (defined $target->[2]) { $target->[2]-> ($node); } else { $r = $node unless defined $r; } } else { # Element my $node = $od-> ($target->[0]->{namespace_uri}, [$target->[0]->{prefix}, $target->[0]->{local_name}]); for (@{ref $target->[0]->{child_nodes} eq 'ARRAY' ? $target->[0]->{child_nodes} : []}) { push @target, [$_, $node]; } for (@{ref $target->[0]->{attributes} eq 'ARRAY' ? $target->[0]->{attributes} : []}) { push @target, [$_, null, $node]; } if (defined $target->[1]) { $target->[1]-> ($node); } else { $r = $node unless defined $r; } } } elsif (defined $target->[0]->{data}) { # Text if (defined $target->[1]) { $target->[1]-> ($target->[0]->{data}); } elsif (not defined $r) { $r = $od-> (''); $r-> ($target->[0]->{data}); } } elsif (defined $target->[0]->{xml_version}) { # Document my $node = $self->; $node-> (false); $node-> -> ( => false); $node-> ($target->[0]->{xml_version}); for (@{ref $target->[0]->{child_nodes} eq 'ARRAY' ? $target->[0]->{child_nodes} : []}) { push @target, [$_, $node]; } unless (defined $r) { $r = $node; $od = $node; $orig_strict = true; } } else { # Document fragment unless (defined $r) { $r = $od->; for (@{ref $target->[0]->{child_nodes} eq 'ARRAY' ? $target->[0]->{child_nodes} : []}) { push @target, [$_, $r]; } } } } $od-> ($orig_strict); if ($r-> == ) { $r-> -> ( => null); } }__; @Test: @@QName: TreeStore.1.test @@enDesc: A non-NS element. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_element_ns (null, 'element'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.2.test @@enDesc: An NS element. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_element_ns ('about:', 'a:element'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.3.test @@enDesc: A non-NS attribute. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_attribute_ns (null, 'element'); $e1->value ('attr value'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.4.test @@enDesc: An NS attribute. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_attribute_ns ('about:', 'a:element'); $e1->value ('attr value'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.5.test @@enDesc: A text. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_text_node ('text value'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.6.test @@enDesc: A cdata section. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_cdata_section ('text value'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->id ('nodeType'); $test->assert_num_equals (actual_value => $e3->node_type, expected_value => ); $test->id ('nodeValue'); $test->assert_equals ($e3->node_value, $e1->node_value); @Test: @@QName: TreeStore.7.test @@enDesc: A document. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc; my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.8.test @@enDesc: A document fragment. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_document_fragment; my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.9.test @@enDesc: A nesting element. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_element_ns (null, 'el1'); $e1->append_child ($doc->create_element_ns (null, 'el2')); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.10.test @@enDesc: A nesting element with text. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_element_ns (null, 'el1'); $e1->manakai_append_text ('text value'); $e1->append_child ($doc->create_element_ns (null, 'el2')); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.12.test @@enDesc: An element with attributes. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_element_ns (null, 'el1'); $e1->set_attribute (a => 'b'); $e1->set_attribute_ns ('about:', 'b:c', 'd'); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.13.test @@enDesc: A document with element. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc; $doc->append_child ($doc->create_element_ns (null, 'el1')); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); @Test: @@QName: TreeStore.14.test @@enDesc: A document fragment with element. @@PerlDef: my $impl; __CODE{tst|createImplForTest:: $impl => $impl}__; my $doc = $impl->create_document; my $e1 = $doc->create_document_fragment; $e1->append_child ($doc->create_element_ns (null, 'el1')); my $e2 = $impl->create_storable_object_from_node ($e1); my $e3 = $impl->create_node_from_storable_object ($e2); $test->assert_num_equals (actual_value => $e3, expected_value => $e1); ##DOMImplementationTreeStore ResourceDef: @QName: StorableObject @AliasFor: DOMMain|DOMObject ElementTypeBinding: @Name: enDesc @ElementType: dis:Description @ShadowContent: @@lang:en ElementTypeBinding: @Name: enImplNote @ElementType: dis:ImplNote @ShadowContent: @@lang:en ElementTypeBinding: @Name: enFN @ElementType: dis:FullName @ShadowContent: @@lang:en ElementTypeBinding: @Name: PerlDef @ElementType: dis:Def @ShadowContent: @@ContentType: lang:Perl @@ForCheck: ManakaiDOM|ForClass