1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
* $Id: XsltFilter.java,v 1.1 2003-02-01 02:10:22 cbj Exp $
* Copyright (C) 2001 David Brownell
*
* This file is part of GNU JAXP, a library.
*
* GNU JAXP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNU JAXP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* As a special exception, if you link this library with other files to
* produce an executable, this library does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* This exception does not however invalidate any other reasons why the
* executable file might be covered by the GNU General Public License.
*/
package gnu.xml.pipeline;
import java.io.IOException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
/**
* Packages an XSLT transform as a pipeline component.
* Note that all DTD events (callbacks to DeclHandler and DTDHandler
* interfaces) are discarded, although XSLT transforms may be set up to
* use the LexicalHandler to write DTDs with only an external subset.
* Not every XSLT engine will necessarily be usable with this filter,
* but current versions of
* <a href="http://saxon.sourceforge.net">SAXON</a> and
* <a href="http://xml.apache.org/xalan-j">Xalan</a> should work well.
*
* @see TransformerFactory
*
* @author David Brownell
* @version $Date: 2003-02-01 02:10:22 $
*/
final public class XsltFilter extends EventFilter
{
/**
* Creates a filter that performs the specified transform.
* Uses the JAXP 1.1 interfaces to access the default XSLT
* engine configured for in the current execution context,
* and parses the stylesheet without custom EntityResolver
* or ErrorHandler support.
*
* @param stylesheet URI for the stylesheet specifying the
* XSLT transform
* @param next provides the ContentHandler and LexicalHandler
* to receive XSLT output.
* @exception SAXException if the stylesheet can't be parsed
* @exception IOException if there are difficulties
* bootstrapping the XSLT engine, such as it not supporting
* SAX well enough to use this way.
*/
public XsltFilter (String stylesheet, EventConsumer next)
throws SAXException, IOException
{
// First, get a transformer with the stylesheet preloaded
TransformerFactory tf = null;
TransformerHandler th;
try {
SAXTransformerFactory stf;
tf = TransformerFactory.newInstance ();
if (!tf.getFeature (SAXTransformerFactory.FEATURE) // sax inputs
|| !tf.getFeature (SAXResult.FEATURE) // sax outputs
|| !tf.getFeature (StreamSource.FEATURE) // stylesheet
)
throw new IOException ("XSLT factory ("
+ tf.getClass ().getName ()
+ ") does not support SAX");
stf = (SAXTransformerFactory) tf;
th = stf.newTransformerHandler (new StreamSource (stylesheet));
} catch (TransformerConfigurationException e) {
throw new IOException ("XSLT factory ("
+ (tf == null
? "none available"
: tf.getClass ().getName ())
+ ") configuration error, "
+ e.getMessage ()
);
}
// Hook its outputs up to the pipeline ...
SAXResult out = new SAXResult ();
out.setHandler (next.getContentHandler ());
try {
LexicalHandler lh;
lh = (LexicalHandler) next.getProperty (LEXICAL_HANDLER);
out.setLexicalHandler (lh);
} catch (Exception e) {
// ignore
}
th.setResult (out);
// ... and make sure its inputs look like ours.
setContentHandler (th);
setProperty (LEXICAL_HANDLER, th);
}
}
|