/[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.2 - (show annotations)
Thu May 1 17:03:52 2003 UTC (21 years ago) by joko
Branch: MAIN
Changes since 1.1: +73 -20 lines
revamped processing: a) _calculate and b) _apply (NEW)

1 ##############################################################################
2 #
3 # Perl module: XML::XUpdate::XSLT
4 #
5 # By Andreas Motl, andreas.motl@ilo.de
6 #
7 # $Id: XSLT.pm,v 1.1 2003/04/30 02:36:32 joko Exp $
8 #
9 # $Log: XSLT.pm,v $
10 # Revision 1.1 2003/04/30 02:36:32 joko
11 # initial commit
12 #
13 #
14 ###############################################################################
15
16 =head1 NAME
17
18 XML::XUpdate::XSLT - A perl module for updating xml documents using XUpdate via XSLT.
19
20 =cut
21
22
23 ######################################################################
24 package XML::XUpdate::XSLT;
25 ######################################################################
26
27 use strict;
28 use warnings;
29
30 use XML::XSLT 0.41;
31 use Carp;
32 use Data::Dumper;
33
34 # Namespace constants
35
36 use constant NS_XUPDATE => 'http://www.xmldb.org/xupdate';
37
38 use vars qw ( $VERSION );
39
40 $VERSION = '0.02';
41
42
43 ######################################################################
44 # PUBLIC DEFINITIONS
45
46 sub new {
47 my $class = shift;
48 my $self = bless {}, $class;
49 my $args = $self->__parse_args(@_);
50
51 $self->{DEBUG} = $args->{debug};
52 $self->{WARNINGS} = $args->{warnings};
53
54 $self->__init_default_macros();
55
56 return $self;
57
58 }
59
60 sub get_stylesheet {
61 my $self = shift;
62 my $name = shift;
63 return $self->{XML}->{xsl}->{$name};
64 }
65
66 sub set_stylesheet {
67 my $self = shift;
68 my $name = shift;
69 my $xml = shift;
70 my $options = shift;
71 if ($options->{encap}) {
72 $xml = qq(<?xml version="1.0" encoding="ISO-8859-1"?>
73
74 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
75
76 <!--
77 This XML Stylesheet is the result of a translation from
78 XUpdate lingo. It actually applies the payload to the
79 original xml document. (it's the second processing step!)
80 -->
81
82 <xsl:output method="xml" />
83
84 $xml
85
86 </xsl:stylesheet>
87 );
88 }
89 $self->{XML}->{xsl}->{$name} = $xml;
90 }
91
92 sub open_document {
93 my $self = shift;
94 my $xml = shift;
95 # FIXME: check for filename, filehandle and URL (etc.)
96 $self->{XML}->{document} = $xml;
97 }
98
99 sub open_xupdate {
100 my $self = shift;
101 my $xml = shift;
102 # FIXME: check for filename, filehandle and URL (etc.)
103 $self->{XML}->{xupdate} = $xml;
104 }
105
106 sub process {
107 my $self = shift;
108 $self->_calculate();
109 $self->_apply();
110 }
111
112 # First, translate the xupdate payload to xsl.
113 # FIXME: do DOM only!
114 sub _calculate {
115 my $self = shift;
116 $self->{XSLT_ENGINE_PREP} = XML::XSLT->new(
117 Source => $self->get_stylesheet("xupdate2xsl"),
118 debug => $self->{DEBUG},
119 warnings => $self->{WARNINGS}
120 );
121 $self->{XSLT_ENGINE_PREP}->open_xml( $self->{XML}->{xupdate} );
122 $self->{XSLT_ENGINE_PREP}->process();
123 $self->set_stylesheet( "_worker", $self->{XSLT_ENGINE_PREP}->toString(), { encap => 1 } );
124 }
125
126 # After that, use this worker xsl to actually apply the changes to the original document.
127 # FIXME: do DOM only!
128 sub _apply {
129 my $self = shift;
130 #print $self->get_stylesheet("_worker"), "\n";
131 #return;
132 $self->{XSLT_ENGINE_LIVE} = XML::XSLT->new(
133 Source => $self->get_stylesheet("_worker"),
134 debug => $self->{DEBUG},
135 warnings => $self->{WARNINGS}
136 );
137 $self->{XSLT_ENGINE_LIVE}->open_xml( $self->{XML}->{document} );
138 $self->{XSLT_ENGINE_LIVE}->process();
139 $self->{XML}->{result} = $self->{XSLT_ENGINE_LIVE}->toString();
140 }
141
142
143 sub toString {
144 my $self = shift;
145 return $self->{XML}->{result};
146 }
147
148
149 ######################################################################
150 # AUXILIARY METHODS
151
152 # Argument parsing (with backwards compatibility hook).
153 sub __parse_args {
154 my $self = shift;
155 my %args;
156
157 if(@_ % 2 ) {
158 $args{dummy} = shift;
159 %args = (%args, @_);
160 } else {
161 %args = @_;
162 }
163
164 return \%args;
165 }
166
167
168 sub __init_default_macros {
169 my $self = shift;
170 $self->{XML}->{xsl}->{xupdate2xsl} = qq(<?xml version="1.0" encoding="ISO-8859-1"?>
171
172 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
173
174 <!--
175 Purpose of this XML Stylesheet is to implement a set of templates
176 to translate XUpdate lingo into an intermediate xslt stylesheet
177 which actually performs the update to the original xml document
178 in a second step.
179 -->
180
181 <xsl:output method="xml" />
182
183 <!-- 1. This is the passthru logic (copy all untouched nodes). -->
184 <xsl:template name="passthru"><xsl:copy><xsl:apply-templates /></xsl:copy></xsl:template>
185 <!-- activate this -->
186 <xsl:template match="*"><xsl:call-template name="passthru" /></xsl:template>
187 <!-- override some builtin rules: see http://www.w3.org/TR/xslt#built-in-rule -->
188 <xsl:template match="comment()"><xsl:call-template name="passthru" /></xsl:template>
189
190 <!-- 2. This is the translation part: XUpdate becomes XSLT -->
191
192 <!-- This node "encapsulates" common infrastructure. -->
193 <xsl:template match="xupdate:modifications">
194
195 <!-- 1. This is the passthru logic (copy all untouched nodes). -->
196 <!-- in fact this is the xsl from above translated to be able to be generated by xsl itself! -->
197 <xsl:comment> 1. passthru logic </xsl:comment>
198 <xsl:element name="xsl:template">
199 <xsl:attribute name="name">passthru</xsl:attribute>
200 <xsl:element name="xsl:copy"><xsl:element name="xsl:apply-templates" /></xsl:element>
201 </xsl:element>
202 <xsl:element name="xsl:template">
203 <xsl:attribute name="match">*</xsl:attribute>
204 <xsl:element name="xsl:call-template"><xsl:attribute name="name">passthru</xsl:attribute></xsl:element>
205 </xsl:element>
206 <xsl:element name="xsl:template">
207 <xsl:attribute name="match">comment()</xsl:attribute>
208 <xsl:element name="xsl:call-template"><xsl:attribute name="name">passthru</xsl:attribute></xsl:element>
209 </xsl:element>
210
211 <!-- continue with all inline nodes -->
212 <xsl:apply-templates />
213
214 </xsl:template>
215
216 <!-- This node "encapsulates" infrastructure for handling the directives. -->
217 <xsl:template match="xupdate:insert-after">
218 <xsl:comment> 2. context finder </xsl:comment>
219 <xsl:apply-templates />
220 </xsl:template>
221
222 <!-- This node passes through all attributes and childnodes rewriting the tagname only. -->
223 <xsl:template match="xupdate:element">
224 <xsl:comment> 3. rewrite / vivify elements/attributes </xsl:comment>
225 <xsl:element name="xsl:element">
226 <xsl:copy-of select="@*"/>
227 <xsl:apply-templates />
228 </xsl:element>
229 </xsl:template>
230
231 <!-- This node passes through all attributes and childnodes rewriting the tagname only. -->
232 <xsl:template match="xupdate:attribute">
233 <xsl:element name="xsl:attribute">
234 <xsl:copy-of select="@*"/>
235 <xsl:apply-templates />
236 </xsl:element>
237 </xsl:template>
238
239 </xsl:stylesheet>
240
241 );
242
243 }
244
245 1;
246 __END__

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