File Coverage

blib/lib/XML/SAXDriver/Sablotron.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             #
2             # The contents of this file are subject to the Mozilla Public
3             # License Version 1.1 (the "License"); you may not use this file
4             # except in compliance with the License. You may obtain a copy of
5             # the License at http://www.mozilla.org/MPL/
6             #
7             # Software distributed under the License is distributed on an "AS
8             # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9             # implied. See the License for the specific language governing
10             # rights and limitations under the License.
11             #
12             # The Original Code is the XML::Sablotron module.
13             #
14             # The Initial Developer of the Original Code is Ginger Alliance Ltd.
15             # Portions created by Ginger Alliance are
16             # Copyright (C) 1999-2000 Ginger Alliance Ltd.
17             # All Rights Reserved.
18             #
19             # Contributor(s):
20             #
21             # Alternatively, the contents of this file may be used under the
22             # terms of the GNU General Public License Version 2 or later (the
23             # "GPL"), in which case the provisions of the GPL are applicable
24             # instead of those above. If you wish to allow use of your
25             # version of this file only under the terms of the GPL and not to
26             # allow others to use your version of this file under the MPL,
27             # indicate your decision by deleting the provisions above and
28             # replace them with the notice and other provisions required by
29             # the GPL. If you do not delete the provisions above, a recipient
30             # may use your version of this file under either the MPL or the
31             # GPL.
32             #
33              
34             package XML::SAXDriver::Sablotron;
35              
36 1     1   714 use strict;
  1         2  
  1         33  
37 1     1   5 use warnings;
  1         2  
  1         30  
38              
39 1     1   1394 use XML::Sablotron;
  0            
  0            
40             use XML::Sablotron::DOM;
41             use XML::SAX::Base;
42              
43             use vars qw($VERSION @ISA);
44              
45             $VERSION = '0.30';
46             @ISA = qw(XML::SAX::Base);
47              
48              
49             sub new {
50             my ($class, %opt) = @_;
51             $class = ref $class || $class;
52             my $self = { Stylesheet => $opt{Stylesheet},
53             Handler => $opt{Handler},
54             _sab_handlers => $opt{SablotHandlers},
55             ret => 0,
56             };
57             bless $self, $class;
58             return $self;
59             }
60              
61             sub parse_uri {
62             my ($self, $uri) = @_;
63             my $sit = new XML::Sablotron::Situation;
64             my $sab = new XML::Sablotron;
65            
66             $self->setSablotHandlers($sab);
67             $sab->regHandler(2, $self);
68             $sab->process($sit, $self->{Stylesheet}, $uri, "arg:/null");
69              
70             return $self->{ret};
71             }
72              
73             sub parse_string {
74             my ($self, $str) = @_;
75             my $sit = new XML::Sablotron::Situation;
76             my $sab = new XML::Sablotron;
77              
78             $self->setSablotHandlers($sab);
79             $sab->regHandler(2, $self);
80             $sab->addArg($sit, "_data", $str);
81             $sab->process($sit, $self->{Stylesheet}, "arg:/_data", "arg:/null");
82              
83             return $self->{ret};
84             }
85              
86             sub parse_dom {
87             my ($self, $dom) = @_;
88             my $sit = new XML::Sablotron::Situation;
89             my $sab = new XML::Sablotron;
90             my $templ = XML::Sablotron::DOM::parseStylesheet($sit,$self->{Stylesheet});
91              
92             $self->setSablotHandlers($sab);
93             $sab->regHandler(2, $self);
94             $sab->addArgTree($sit, 'data', $dom);
95             $sab->addArgTree($sit, 'template', $templ);
96             $sab->process($sit, 'arg:/template', 'arg:/data', 'arg:/null');
97              
98             return $self->{ret};
99             }
100              
101             sub setSablotHandlers {
102             my $self = shift;
103             my $sab = shift;
104             my $h;
105              
106             $h = $self->{_sab_handlers}{SchemeHandler};
107             $sab->regHandler(1, $h) if $h;
108              
109             $h = $self->{_sab_handlers}{MessageHandler};
110             $sab->regHandler(0, $h) if $h;
111              
112             $h = $self->{_sab_handlers}{MiscHandler};
113             $sab->regHandler(3, $h) if $h;
114             }
115              
116             ############################################################
117             # SAX-like handler for Sablotron
118             ############################################################
119              
120             sub SAXStartDocument {
121             my ($self, $proc) = @_;
122             $self->SUPER::start_document;
123             $self->{_pending_ns} = {};
124             $self->{_ns_stack} = [{}]; #one empty slot
125             $self->{_ele_stack} = [];
126             }
127              
128             sub SAXStartNamespace {
129             my ($self, $proc, $prefix, $uri) = @_;
130             #print "---> SAXStartNamespace: $prefix, $uri\n";
131              
132             $self->{_pending_ns}{$prefix} = $uri;
133             $self->SUPER::start_prefix_mapping({Prefix => $prefix,
134             NamespaceURI => $uri});
135             }
136              
137             sub SAXEndNamespace {
138             my ($self, $proc, $prefix) = @_;
139             #print "---> SAXEndNamespace: $prefix\n";
140             $self->SUPER::end_prefix_mapping({Prefix => $prefix});
141             }
142              
143             sub SAXStartElement {
144             my ($self, $proc, $name, %atts) = @_;
145             #print "---> SAXStartElement: $name ";
146             #print join " ", map {"$_=$atts{$_}"} keys %atts;
147             #print "\n";
148              
149             #update namespace mappings
150             my $ns = ${$self->{_ns_stack}}[-1];
151             while (my($a, $b) = each %{$self->{_pending_ns}}) {
152             $$ns{$a} = $b;
153             }
154             push @{$self->{_ns_stack}}, $ns;
155             $self->{_pending_ns} = {};
156              
157             #create element for the SAX call
158             my $ele = {Name => $name};
159              
160             #ns stuff
161             my ($le, $pe);
162             if (1) {
163             if ($name =~ /(.*?):(.*)/) {
164             $pe = $1; $le = $2;
165             } else {
166             $pe = ""; $le = $name;
167             }
168             $$ele{NamespaceURI} = $$ns{$pe};
169             $$ele{Prefix} = $pe;
170             $$ele{LocalName} = $le;
171             }
172              
173             #attributes
174             my $saxatts = {};
175             foreach my $att (keys %atts) {
176             my ($la, $pa);
177             if ($att =~ /(.*?):(.*)/) {
178             $pa = $1; $la = $2;
179             } else {
180             $pa = ""; $la = $att;
181             }
182             my $uri = $$ns{$pa ? $pa : $pe};
183             my $key = "$la";
184             $key = "{$uri}" . $key if $uri;
185             $$saxatts{$key} = {Name => "$att",
186             Value => $atts{$att},
187             NamespaceURI => $uri,
188             Prefix => $pa,
189             LocalName => $la,
190             };
191             }
192             $$ele{Attributes} = $saxatts;
193              
194             $self->SUPER::start_element($ele);
195             delete $$ele{Attributes}; #save element for later use
196             push @{$self->{_ele_stack}}, $ele;
197             }
198              
199             sub SAXEndElement {
200             my ($self, $proc, $name) = @_;
201             #print "---> SAXEndElement: $name\n";
202              
203             $self->SUPER::end_element(pop @{$self->{_ele_stack}});
204             pop @{$self->{_ns_stack}};
205             }
206              
207             sub SAXCharacters {
208             my ($self, $proc, $data) = @_;
209             #print "---> SAXCharacters: $data\n";
210             $self->SUPER::characters({Data => $data});
211             }
212              
213             sub SAXComment {
214             my ($self, $proc, $data) = @_;
215             #print "---> SAXComment: $data\n";
216             $self->SUPER::comment({Data => $data});
217             }
218              
219             sub SAXPI {
220             my ($self, $proc, $target, $data) = @_;
221             #print "---> SAXPI: $target, $data\n";
222             $self->SUPER::processing_instruction({Target => $target, Data => $data});
223             }
224              
225             sub SAXEndDocument {
226             my ($self, $proc) = @_;
227             #print "---> SAXEndDocument\n";
228             $self->{ret} = $self->SUPER::end_document;
229             }
230              
231             1;
232             __END__