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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Thu May 1 17:03:52 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.1: +73 -20 lines
revamped processing: a) _calculate and b) _apply (NEW)

1 joko 1.1 ##############################################################################
2     #
3     # Perl module: XML::XUpdate::XSLT
4     #
5     # By Andreas Motl, andreas.motl@ilo.de
6     #
7 joko 1.2 # $Id: XSLT.pm,v 1.1 2003/04/30 02:36:32 joko Exp $
8 joko 1.1 #
9     # $Log: XSLT.pm,v $
10 joko 1.2 # Revision 1.1 2003/04/30 02:36:32 joko
11     # initial commit
12     #
13 joko 1.1 #
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 joko 1.2 $self->{DEBUG} = $args->{debug};
52     $self->{WARNINGS} = $args->{warnings};
53    
54 joko 1.1 $self->__init_default_macros();
55    
56 joko 1.2 return $self;
57 joko 1.1
58 joko 1.2 }
59 joko 1.1
60 joko 1.2 sub get_stylesheet {
61     my $self = shift;
62     my $name = shift;
63     return $self->{XML}->{xsl}->{$name};
64 joko 1.1 }
65    
66 joko 1.2 sub set_stylesheet {
67 joko 1.1 my $self = shift;
68     my $name = shift;
69 joko 1.2 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 joko 1.1 }
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 joko 1.2 $self->_calculate();
109     $self->_apply();
110 joko 1.1 }
111    
112 joko 1.2 # 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 joko 1.1 sub toString {
144     my $self = shift;
145 joko 1.2 return $self->{XML}->{result};
146 joko 1.1 }
147    
148    
149     ######################################################################
150     # AUXILIARY METHODS
151    
152 joko 1.2 # Argument parsing (with backwards compatibility hook).
153 joko 1.1 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 joko 1.2 $self->{XML}->{xsl}->{xupdate2xsl} = qq(<?xml version="1.0" encoding="ISO-8859-1"?>
171 joko 1.1
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 joko 1.2 which actually performs the update to the original xml document
178     in a second step.
179 joko 1.1 -->
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