ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/SimpleXMLDoc.pm
Revision: 1.6
Committed: Tue Feb 7 16:52:34 2006 UTC (19 years, 3 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_3-p4, V1_0_3-p3, V1_0_3-p2, before110xmlBRmerge, V1_0_3-p1, V1_0_3
Branch point for: v103_with_xml
Changes since 1.5: +4 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #____________________________________________________________________
2 # File: SimpleXMLDoc.pm
3 #____________________________________________________________________
4 #
5 # Author: Shaun Ashby <Shaun.Ashby@cern.ch>
6 # Update: 2005-04-22 17:09:26+0200
7 # Revision: $Id: SimpleXMLDoc.pm,v 1.4 2006/01/19 17:26:29 sashby Exp $
8 #
9 # Copyright: 2005 (C) Shaun Ashby
10 #
11 #--------------------------------------------------------------------
12
13 =head1 NAME
14
15 ActiveDoc::SimpleXMLDoc - Base SCRAM document class.
16
17 =head1 SYNOPSIS
18
19 my $obj = ActiveDoc::SimpleXMLDoc->new();
20
21 =head1 DESCRIPTION
22
23 The ActiveDoc::SimpleXMLDoc class is the base class for all SCRAM documents. It hides all the
24 machinery needed to activate full XML parsing. The XML parser used is XML::Parser::Expat.
25
26 =head1 METHODS
27
28 =over
29
30 =cut
31
32 package ActiveDoc::SimpleXMLDoc;
33 use XML::Parser::Expat;
34 use ActiveDoc::Container;
35 require 5.004;
36 use Exporter;
37
38 @ISA=qw(Exporter);
39 @EXPORT_OK=qw();
40
41 sub new()
42 {
43 ###############################################################
44 # new #
45 ###############################################################
46 # modified : Fri Apr 22 17:10:10 2005 / SFA #
47 # params : #
48 # : #
49 # function : #
50 # : #
51 ###############################################################
52 my $proto=shift;
53 my $class=ref($proto) || $proto;
54 my $self={};
55 bless $self,$class;
56 my @handler_list=('Start','End','Char','Proc','Comment',
57 'Entity','Element','Attlist','Doctype','DoctypeFin'); # DTD handlers
58
59 my ($context, @userhandlers)=@_;
60
61 $CONTAINER=new ActiveDoc::Container; # The base container;
62
63 # Set the default handlers:
64 $self->{DEFAULT_HANDLERS}={ 'Start' => \&open_, 'End' => \&close_,
65 'Char' => \&char_, 'Proc' => \&proc_,
66 'Comment' => \&comment_,
67 'Entity' => \&entity_,
68 'Element' => \&element_,
69 'Attlist' => \&attlist_,
70 'Doctype' => \&doctype_,
71 'DoctypeFin' => \&doctypefin_ };
72
73 # Check each supplied handler. If there's a code ref, we override the
74 # default handler given in this package:
75 my $i;
76 for ($i = 0; $i <= $#userhandlers; $i++)
77 {
78 if (ref($userhandlers[$i]) eq 'CODE')
79 {
80 $self->{DEFAULT_HANDLERS}->{$handler_list[$i]} = $userhandlers[$i];
81 }
82 }
83
84 $self->{CONTEXT}=$context;
85
86 # Initialise the XML parser:
87 $self->{xmlparser} = XML::Parser::Expat->new(ErrorContext => 3,
88 ParseParamEnt => 1);
89
90 # Add the default XML tag handlers:
91 foreach my $handler (@handler_list)
92 {
93 $self->{xmlparser}->setHandlers($handler => $self->{DEFAULT_HANDLERS}->{$handler});
94 }
95
96 return $self;
97 }
98
99 sub parse()
100 {
101 my $self=shift;
102 my ($filename)=@_;
103
104 if (-f $filename)
105 {
106 $self->parsefile_($filename);
107 # Move the data from the container to {data_} key and
108 # also keep a reference to the whole container object
109 # just in case there is other data needed outside of 'content':
110 $self->data();
111 }
112 else
113 {
114 # Error: file not found
115 die "SCRAM SimpleXMLDoc: File \"".$filename."\" not found! Context label = \"".$self->{CONTEXT}."\"\n";
116 }
117 }
118
119 sub register_handlers_()
120 {
121 my $self=shift;
122 # Register tags to the container class:
123 if (@_)
124 {
125 $CONTAINER->register_handlers_(@_);
126 }
127 }
128
129 sub parsefile_()
130 {
131 my $self=shift;
132 my ($filename)=@_;
133 $self->{xmlparser}->parsefile($filename)
134 || $self->{xmlparser}->xpcroak("SCRAM SimpleDoc XML parse error:");
135 # Clean up:
136 delete $self->{xmlparser};
137 }
138
139 sub data()
140 {
141 my $self=shift;
142 $self->{data_} = $CONTAINER->data_();
143 $self->{fulldata_} = $CONTAINER;
144 }
145
146 # The default handlers:
147 sub open_()
148 {
149 my $xmlparser=shift;
150 my ($element, %attributes)=@_;
151 $element=~tr[A-Z][a-z];
152 # Handle document "doc" tags and load a
153 # container class for the document type:
154 if ($element eq 'doc')
155 {
156 if (exists ($attributes{'type'}))
157 {
158 my $doctype=$attributes{'type'}."::Container";
159 eval "require $doctype";
160 if ($@)
161 {
162 print "SCRAM SimpleXMLDoc: Unable to parse the current document because\n";
163 print " the data container type (=DOCTYPE) is invalid!\n";
164 print "\n";
165 die $@,"\n";
166 }
167 # Bless the base container to its real type:
168 bless($CONTAINER,$doctype);
169 }
170 else
171 {
172 die "SCRAM SimpleXMLDoc: Unable to handle a NULL document type!","\n";
173 }
174 return;
175 }
176 else
177 {
178 # Pass the call to the container class. This will use the AUTOLOAD
179 # function of the class:
180 $CONTAINER->open($element);
181 $CONTAINER->$element($element,\%attributes);
182 }
183 }
184
185 sub close_()
186 {
187 my $xmlparser=shift;
188 my ($element)=@_;
189 $element=~tr[A-Z][a-z];
190 return if $element eq 'doc';
191 # Tell the container that the tag ended:
192 $CONTAINER->close($element);
193 }
194
195 sub char_()
196 {
197 my ($xmlparser, @items) = @_;
198 my $string=join("",@items);
199 return if ($string !~ /[a-zA-Z0-9_].*/);
200 # Push the strings onto the container object, just in case
201 # they form part of content for the active tag:
202 $CONTAINER->text_($string);
203 }
204
205 sub proc_()
206 {
207 my ($xmlparser,$target,$data)=@_;
208 }
209
210 sub comment_()
211 {
212 my ($xmlparser,$string)=@_;
213 }
214
215 # Entity (Parser, Name, Val, Sysid, Pubid, Ndata,IsParam)
216 sub entity_()
217 {
218 my ($xmlparser, $name, $val, $sysid, $pubid, $ndata)=@_;
219 }
220
221 # Element (Parser, Name, Model)
222 sub element_()
223 {
224 my ($xmlparser,$name,$model)=@_;
225 }
226
227 # Attlist (Parser, Elname, Attname, Type, Default, Fixed)
228 sub attlist_()
229 {
230 my ($xmlparser,$element, $attname, $type, $default,$fixed)=@_;
231 }
232
233 # Doctype (Parser, Name, Sysid, Pubid, Internal)
234 sub doctype_()
235 {
236 my ($xmlparser,$name,$sysid,$pubid,$internal)=@_;
237 }
238
239 # DoctypeFin (Parser)
240 sub doctypefin_()
241 {
242 my ($xmlparser)=@_;
243 }
244
245 1;
246
247 =back
248
249 =head1 AUTHOR/MAINTAINER
250
251 Shaun ASHBY
252
253 =cut
254