/[cvs]/nfo/perl/libs/XML/XUpdate/XSLT.pm
ViewVC logotype

Contents of /nfo/perl/libs/XML/XUpdate/XSLT.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Thu May 1 23:40:32 2003 UTC (21 years ago) by joko
Branch: MAIN
Changes since 1.3: +9 -2 lines
minor update: commented debugging part

1 ##############################################################################
2 #
3 # Perl module: XML::XUpdate::XSLT
4 #
5 # By Andreas Motl, andreas.motl@ilo.de
6 #
7 # $Id: XSLT.pm,v 1.3 2003/05/01 20:11:49 joko Exp $
8 #
9 # $Log: XSLT.pm,v $
10 # Revision 1.3 2003/05/01 20:11:49 joko
11 # * added pod from xupdate.pl
12 # - extracted xml to external files
13 #
14 # Revision 1.1 2003/04/30 02:36:32 joko
15 # initial commit
16 #
17 #
18 ###############################################################################
19
20 =pod
21
22
23 =head1 NAME
24
25 XML::XUpdate::XSLT - A perl module for updating xml documents using XUpdate via XSLT.
26
27
28 =head3 Overview
29
30 This is not the same xupdate currently available from CPAN at
31 http://search.cpan.org/author/PAJAS/XML-XUpdate-LibXML-0.4.0/xupdate .
32
33 Its intention - however - is identical:
34 xupdate - Process XUpdate commands against an XML document.
35
36
37 =head3 Their implementations differ:
38
39 1. xupdate (by Petr Pajas) uses ...
40 XML::XUpdate::LibXML - Simple implementation of XUpdate format
41
42 ... which is based on XML::LibXML which in turn is:
43 [...]
44 This module is an interface to the gnome libxml2 DOM parser (no SAX parser support yet),
45 and the DOM tree. It also provides an XML::XPath-like findnodes() interface, providing
46 access to the XPath API in libxml2.
47 [...]
48
49 2. This xupdate attempts to implement the XUpdate specs using XSLT only.
50
51
52 =head3 Yet another xupdate - facts in short:
53
54 S: It would be nice to have a pure perl thingy which does (almost) the same stuff....
55
56 Q: Can we achieve compliance with its (XML::XUpdate::LibXML) API? (or just a subset ....)
57
58 Q: Can we achieve the processing using CPAN's XML::XSLT?
59 S: Proposal: XML::XUpdate::XSLT!?
60
61 Q: Can we mimic/use the interface of the - already established - 'xupdate' program???
62
63 Q: Should we follow the CRUD path first? (CRUD means: Create, Retrieve, Update, Delete)
64 S?: Proposal: XML::XUpdate::XSLT::API uses XML::XUpdate::XSLT::CRUD
65
66
67 =head4 Todo
68
69 o What about proper encoding? (ISO-8859-1 or UTF-8)
70 o Is it possible to create the required "xsl_template.xml" at runtime via XSL itself?
71 o Cache contents of external files (*.xml). Performance!
72
73
74 =cut
75
76
77 ######################################################################
78 package XML::XUpdate::XSLT;
79 ######################################################################
80
81 use strict;
82 use warnings;
83
84 use XML::XSLT 0.41;
85 use Carp;
86 use File::Basename;
87 use Data::Dumper;
88
89 # Namespace constants
90
91 use constant NS_XUPDATE => 'http://www.xmldb.org/xupdate';
92
93 use vars qw ( $VERSION );
94
95 $VERSION = '0.01';
96
97
98 ######################################################################
99 # PUBLIC DEFINITIONS
100
101 sub new {
102 my $class = shift;
103 my $self = bless {}, $class;
104 my $args = $self->__parse_args(@_);
105
106 $self->{DEBUG} = $args->{debug};
107 $self->{WARNINGS} = $args->{warnings};
108
109 $self->__init_default_stylesheets();
110
111 return $self;
112
113 }
114
115 sub get_stylesheet {
116 my $self = shift;
117 my $name = shift;
118 return $self->{XML}->{xsl}->{$name};
119 }
120
121 sub set_stylesheet {
122 my $self = shift;
123 my $name = shift;
124 my $xml = shift;
125 my $options = shift;
126 if ($options->{encap}) {
127 my $template = $self->__slurp_file("xsl_template.xml");
128 # FIXME! What about the quirky? Is there a better one?
129 $template =~ s!<xsl:quirky_placeholder />!$xml!;
130 $xml = $template;
131 }
132 $self->{XML}->{xsl}->{$name} = $xml;
133 }
134
135 sub open_document {
136 my $self = shift;
137 my $xml = shift;
138 # FIXME: check for filename, filehandle and URL (etc.)
139 $self->{XML}->{document} = $xml;
140 }
141
142 sub open_xupdate {
143 my $self = shift;
144 my $xml = shift;
145 # FIXME: check for filename, filehandle and URL (etc.)
146 $self->{XML}->{xupdate} = $xml;
147 }
148
149 sub process {
150 my $self = shift;
151 $self->_calculate();
152 $self->_apply();
153 }
154
155 # First, translate the xupdate payload to xsl.
156 # FIXME: do DOM only!
157 sub _calculate {
158 my $self = shift;
159 $self->{XSLT_ENGINE_PREP} = XML::XSLT->new(
160 Source => $self->get_stylesheet("xupdate2xsl"),
161 debug => $self->{DEBUG},
162 warnings => $self->{WARNINGS}
163 );
164 $self->{XSLT_ENGINE_PREP}->open_xml( $self->{XML}->{xupdate} );
165 $self->{XSLT_ENGINE_PREP}->process();
166 $self->set_stylesheet( "_worker", $self->{XSLT_ENGINE_PREP}->toString(), { encap => 1 } );
167 }
168
169 # After that, use this worker xsl to actually apply the changes to the original document.
170 # FIXME: do DOM only!
171 sub _apply {
172 my $self = shift;
173
174 # debug - print the calculated xsl on STDERR
175 #print STDERR $self->get_stylesheet("_worker"), "\n";
176
177 #return;
178 $self->{XSLT_ENGINE_LIVE} = XML::XSLT->new(
179 Source => $self->get_stylesheet("_worker"),
180 debug => $self->{DEBUG},
181 warnings => $self->{WARNINGS}
182 );
183 $self->{XSLT_ENGINE_LIVE}->open_xml( $self->{XML}->{document} );
184 $self->{XSLT_ENGINE_LIVE}->process();
185 $self->{XML}->{result} = $self->{XSLT_ENGINE_LIVE}->toString();
186 }
187
188 sub toString {
189 my $self = shift;
190 return $self->{XML}->{result};
191 }
192
193
194 ######################################################################
195 # AUXILIARY METHODS
196
197 # Argument parsing (with backwards compatibility hook).
198 sub __parse_args {
199 my $self = shift;
200 my %args;
201
202 if(@_ % 2 ) {
203 $args{dummy} = shift;
204 %args = (%args, @_);
205 } else {
206 %args = @_;
207 }
208
209 return \%args;
210 }
211
212
213 sub __init_default_stylesheets {
214 my $self = shift;
215 if (my $payload = $self->__slurp_file("xupdate2xsl.xml")) {
216 $self->{XML}->{xsl}->{xupdate2xsl} = $payload;
217 }
218 }
219
220 sub __slurp_file {
221 my $self = shift;
222 my $filename = shift;
223
224 # does file exist?
225 if (! -e $filename) {
226 $filename = dirname(__FILE__) . "/$filename";
227 if (! -e $filename) {
228 croak("File $filename does not exist.");
229 }
230 }
231
232 open(FH, "<" . $filename);
233 my @lines = <FH>;
234 my $content = join("", @lines);
235 close(FH);
236 return $content;
237 }
238
239 1;
240 __END__

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed