/[suikacvs]/messaging/manakai/lib/Message/Markup/XML/NodeTree.pm
Suika

Contents of /messaging/manakai/lib/Message/Markup/XML/NodeTree.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Sun Feb 22 01:46:23 2004 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
CVS Tags: before-dis2-200411, manakai-release-0-3-2, manakai-release-0-3-1, manakai-release-0-4-0, manakai-200612, HEAD
Changes since 1.2: +3 -3 lines
Qualify internal function name

1
2 =head1 NAME
3
4 Message::Markup::XML::Node --- manakai XML : XML Node Implementation
5
6 =head1 DESCRIPTION
7
8 This module implements the XML Node object.
9
10 This module is part of manakai XML.
11
12 =cut
13
14 package Message::Markup::XML::NodeTree;
15 use strict;
16 our $VERSION = do{my @r=(q$Revision: 1.2 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
17 use Message::Markup::XML::Node;
18 use Message::Markup::XML::QName qw/:prefix :special-uri/;
19 use Exporter;
20 push our @ISA, 'Exporter';
21
22 our @EXPORT_OK = qw/construct_xml_tree/;
23
24 =head1 METHODS
25
26 =over 4
27
28 =cut
29
30 sub construct_xml_tree (%);
31 sub construct_xml_tree (%) {
32 my %opt = @_;
33 my $parent = $opt{parent} || 'Message::Markup::XML::Node';
34 my $method = ref $opt{parent} ? 'append_new_node' : 'new';
35 my $node = $parent->$method (map {$_=>$opt{$_}} grep /^[^-]/, keys %opt);
36 for (keys %{$opt{-attr}||{}}) {
37 $node->set_attribute ($_ => $opt{-attr}->{$_});
38 }
39 for (@{$opt{-child}||[]}) {
40 construct_xml_tree (%$_, parent => $node);
41 }
42 for (keys %{$opt{-ns}||{}}) {
43 $node->{ns}->{ $_
44 || ($_ eq '0' ? '0' : DEFAULT_PFX) }
45 = $opt{-ns}->{$_}
46 || ($opt{-ns}->{$_} eq '0' ? ZERO_URI
47 : NULL_URI);
48 }
49 $node;
50 }
51
52
53 #------- Not (re-)Implemented Yet -------
54
55 my %NS;
56 sub merge_external_subset ($) {
57 my $self = shift;
58 unless ($self->{type} eq '#declaration'
59 && $self->{namespace_uri} eq $NS{SGML}.'doctype') {
60 return unless $self->{type} eq '#document' || $self->{type} eq '#fragment';
61 for (@{$self->{node}}) {
62 $_->merge_external_subset;
63 }
64 return;
65 }
66 my $xsub = $self->get_attribute ('external-subset');
67 return unless ref $xsub;
68 for (@{$xsub->{node}}) {
69 $_->{parent} = $self;
70 }
71 push @{$self->{node}}, @{$xsub->{node}};
72 $self->remove_child_node ($xsub);
73 $self->remove_child_node ($self->get_attribute ('PUBLIC'));
74 $self->remove_child_node ($self->get_attribute ('SYSTEM'));
75 $self->remove_marked_section;
76 }
77
78 sub remove_marked_section ($) {
79 my $self = shift;
80 my @node;
81 for (@{$self->{node}}) {
82 if ({qw/#declaration 1 #element 1 #section 1 #reference 1 #attribute 1
83 #document 1 #fragment 1/}->{$_->{type}}) {
84 $_->remove_marked_section;
85 }
86 }
87 for (@{$self->{node}}) {
88 if ($_->{type} ne '#section') {
89 push @node, $_;
90 } else {
91 my $status = $_->get_attribute ('status', make_new_node => 1)->inner_text;
92 if ($status eq 'CDATA') {
93 $_->{type} = '#text';
94 $_->remove_attribute ('status');
95 push @node, $_;
96 } elsif ($status ne 'IGNORE') { # INCLUDE
97 for my $e (@{$_->{node}}) {
98 if ($e->{type} ne '#attribute') {
99 $e->{parent} = $self;
100 push @node, $e;
101 }
102 }
103 }
104 }
105 }
106 $self->{node} = \@node;
107 }
108
109 ## TODO: references in EntityValue
110 sub remove_references ($) {
111 my $self = shift;
112 my @node;
113 for (@{$self->{node}}) {
114 if ({qw/#declaration 1 #element 1 #section 1 #reference 1 #attribute 1
115 #document 1 #fragment 1/}->{$_->{type}}) {
116 $_->remove_references;
117 }
118 }
119 for (@{$self->{node}}) {
120 if ($_->{type} ne '#reference'
121 || ($self->{type} eq '#declaration'
122 && $_->{namespace_uri} eq $NS{SGML}.'entity')) {
123 push @node, $_;
124 } else {
125 if (index ($_->{namespace_uri}, 'char') > -1) {
126 my $e = ref ($_)->new (type => '#text', value => chr $_->{value});
127 $e->{parent} = $self;
128 push @node, $e;
129 } elsif ($_->{flag}->{smxp__ref_expanded}) {
130 for my $e (@{$_->{node}}) {
131 if ($e->{type} ne '#attribute') {
132 $e->{parent} = $self;
133 push @node, $e;
134 }
135 }
136 } else { ## reference is not expanded
137 push @node, $_;
138 }
139 }
140 $_->{flag}->{smxp__defined_with_param_ref} = 0
141 if $_->{flag}->{smxp__defined_with_param_ref}
142 && !$_->{flag}->{smxp__non_processed_declaration};
143 }
144 $self->{node} = \@node;
145 }
146
147 sub resolve_relative_uri ($;$%) {
148 require URI;
149 my ($self, $rel, %o) = @_;
150 my $base = $self->get_attribute ('base', namespace_uri => $NS{xml});
151 $base = ref ($base) ? $base->inner_text : $NS{default_base_uri};
152 if ($base !~ /^[0-9A-Za-z.%+-]+:/) { # $base is relative
153 $base = $self->Message::Markup::XML::NodeTree::_resolve_relative_uri_by_parent ($base, \%o);
154 }
155 eval q{ ## Catch error such as $base is 'data:,foo' (non hierarchic scheme,...)
156 return URI->new ($rel)->abs ($base || '.'); ## BUG (or spec) of URI: $base == false
157 } or return $rel;
158 }
159 sub _resolve_relative_uri_by_parent ($$$) {
160 my ($self, $rel, $o) = @_;
161 if (ref $self->{parent}) {
162 if (!$o->{use_references_base_uri} && $self->{parent}->{type} eq '#reference') {
163 ## This case is necessary to work with
164 ## <element> <!-- element can have base URI -->
165 ## text <!-- text cannot have base URI -->
166 ## &ent; <!-- ref's base URI is referred entity's one (in this module) -->
167 ## <!-- expantion of ent -->
168 ## entity's text <!-- text cannot have base URI, so use <element>'s one -->
169 ## <entitys-element/> <!-- element can have base URI, otherwise ENTITY's one -->
170 ## </element>
171 return $self->{parent}->_resolve_relative_uri_by_parent ($rel, $o);
172 } else {
173 return $self->{parent}->resolve_relative_uri ($rel, %$o);
174 }
175 } else {
176 return $rel;
177 }
178 }
179
180 sub root_node ($) {
181 my $self = shift;
182 if ($self->{type} eq '#document') {
183 return $self;
184 } elsif (ref $self->{parent}) {
185 return $self->{parent}->root_node;
186 } else {
187 return $self;
188 }
189 }
190
191 sub _get_entity_manager ($) {
192 my $self = shift;
193 if ($self->{type} eq '#document') {
194 unless ($self->{flag}->{smx__entity_manager}) {
195 require Message::Markup::XML::EntityManager;
196 $self->{flag}->{smx__entity_manager} = Message::Markup::XML::EntityManager->new ($self);
197 }
198 return $self->{flag}->{smx__entity_manager};
199 } elsif (ref $self->{parent}) {
200 return $self->{parent}->_get_entity_manager;
201 } else {
202 unless ($self->{flag}->{smx__entity_manager}) {
203 require Message::Markup::XML::EntityManager;
204 $self->{flag}->{smx__entity_manager} = Message::Markup::XML::EntityManager->new ($self);
205 }
206 return $self->{flag}->{smx__entity_manager};
207 }
208 }
209
210 =head1 LICENSE
211
212 Copyright 2003 Wakaba <[email protected]>
213
214 This program is free software; you can redistribute it and/or
215 modify it under the same terms as Perl itself.
216
217 =cut
218
219 1; # $Date: 2004/02/14 11:08:45 $

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24