001: package net.sf.saxon.sxpath;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.event.Builder;
005: import net.sf.saxon.event.Stripper;
006: import net.sf.saxon.expr.Expression;
007: import net.sf.saxon.expr.ExpressionTool;
008: import net.sf.saxon.instruct.SlotManager;
009: import net.sf.saxon.om.AllElementStripper;
010: import net.sf.saxon.om.NamePool;
011: import net.sf.saxon.om.NamespaceResolver;
012: import net.sf.saxon.om.NodeInfo;
013: import net.sf.saxon.trans.IndependentContext;
014: import net.sf.saxon.trans.XPathException;
015: import net.sf.saxon.type.Type;
016:
017: import javax.xml.transform.Source;
018: import javax.xml.transform.stream.StreamSource;
019: import java.io.File;
020: import java.util.List;
021:
022: /**
023: * This is a cut-down version of the XPathEvaluator in the net.sf.saxon.xpath package. It provides
024: * much of the same functionality, but without any dependencies on the JAXP 1.3 interfaces, which
025: * are not available in JDK 1.4. The main restrictions are that it does not support mechanisms for
026: * defining variables or functions.
027: *
028: * @author Michael H. Kay
029: */
030:
031: public class XPathEvaluator {
032:
033: private IndependentContext staticContext;
034: private boolean stripSpace = false;
035:
036: /**
037: * Default constructor. Creates an XPathEvaluator with a default configuration and name pool.
038: */
039:
040: public XPathEvaluator() {
041: this (new Configuration());
042: }
043:
044: /**
045: * Construct an XPathEvaluator with a specified configuration.
046: * @param config the configuration to be used
047: */
048: public XPathEvaluator(Configuration config) {
049: staticContext = new IndependentContext(config);
050: }
051:
052: /**
053: * Get the Configuration in use
054: */
055:
056: public Configuration getConfiguration() {
057: return staticContext.getConfiguration();
058: }
059:
060: /**
061: * Indicate whether all whitespace text nodes in the source document are to be
062: * removed.
063: * @param strip True if all whitespace text nodes are to be stripped from the source document,
064: * false otherwise. The default if the method is not called is false.
065: */
066:
067: public void setStripSpace(boolean strip) {
068: stripSpace = strip;
069: }
070:
071: /**
072: * Build a source document.
073: * @param source a JAXP Source object. This may be any implementation of Source that Saxon recognizes:
074: * not only the standard kinds of source such as StreamSource, SAXSource, and DOMSource, but also for
075: * example a JDOM or XOM DocumentWrapper.
076: * @return the NodeInfo representing the root of the constructed tree.
077: * @throws XPathException if, for example, XML parsing fails.
078: */
079:
080: public NodeInfo build(Source source) throws XPathException {
081: NamePool pool;
082: if (source instanceof NodeInfo) {
083: pool = ((NodeInfo) source).getNamePool();
084: } else {
085: pool = NamePool.getDefaultNamePool();
086: }
087: Stripper stripper = null;
088: if (stripSpace) {
089: stripper = AllElementStripper.getInstance();
090: }
091: Configuration config = new Configuration();
092: config.setNamePool(pool);
093: return Builder.build(source, stripper, config);
094: }
095:
096: /**
097: * Set the static context for compiling XPath expressions. This provides control over the
098: * environment in which the expression is compiled, for example it allows namespace prefixes to
099: * be declared, variables to be bound and functions to be defined. For most purposes, the static
100: * context can be defined by providing and tailoring an instance of the IndependentContext class.
101: * Until this method is called, a default static context is used, in which no namespaces are defined
102: * other than the standard ones (xml, xslt, and saxon), and no variables or functions (other than the
103: * core XPath functions) are available.
104: */
105:
106: public void setStaticContext(IndependentContext context) {
107: staticContext = context;
108: }
109:
110: /**
111: * Get the current static context. This will always return a value; if no static context has been
112: * supplied by the user, the system creates its own.
113: */
114:
115: public IndependentContext getStaticContext() {
116: return staticContext;
117: }
118:
119: /**
120: * Prepare an XPath expression for subsequent evaluation.
121: * @param expression The XPath expression to be evaluated, supplied as a string.
122: * @return an XPathExpression object representing the prepared expression
123: * @throws XPathException if the syntax of the expression is wrong, or if it references namespaces,
124: * variables, or functions that have not been declared.
125: */
126:
127: public XPathExpression createExpression(String expression)
128: throws XPathException {
129: Expression exp = ExpressionTool.make(expression, staticContext,
130: 0, -1, 1);
131: exp = exp.typeCheck(staticContext, Type.ITEM_TYPE);
132: SlotManager map = staticContext.getConfiguration()
133: .makeSlotManager();
134: ExpressionTool.allocateSlots(exp, 0, map);
135: XPathExpression xpe = new XPathExpression(this , exp);
136: xpe.setStackFrameMap(map);
137: return xpe;
138: }
139:
140: /**
141: * Set the external namespace resolver to be used. This overrides any namespaces declared directly
142: * using declareNamespace on the staticContext object
143: * @param namespaceContext The namespace context
144: */
145:
146: public void setNamespaceResolver(NamespaceResolver namespaceContext) {
147: staticContext.setNamespaceResolver(namespaceContext);
148: }
149:
150: /**
151: * Get the external namespace resolver, if one has been set using {@link #setNamespaceResolver}
152: * @return the namespace context if set, or null otherwise
153: */
154:
155: public NamespaceResolver getNamespaceResolver() {
156: return staticContext.getNamespaceResolver();
157: }
158:
159: /**
160: * A simple command-line interface for the XPathEvaluator (not documented).
161: * First parameter is the filename containing the source document, second
162: * parameter is the XPath expression.
163: */
164:
165: public static void main(String[] args) throws Exception {
166: if (args.length != 2) {
167: System.err
168: .println("format: java XPathEvaluator source.xml \"expression\"");
169: return;
170: }
171: XPathEvaluator xpe = new XPathEvaluator();
172: XPathExpression exp = xpe.createExpression(args[1]);
173: List results = exp
174: .evaluate(new StreamSource(new File(args[0])));
175: for (int i = 0; i < results.size(); i++) {
176: Object o = results.get(i);
177: System.err.println(o);
178: }
179: }
180:
181: }
182:
183: //
184: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
185: // you may not use this file except in compliance with the License. You may obtain a copy of the
186: // License at http://www.mozilla.org/MPL/
187: //
188: // Software distributed under the License is distributed on an "AS IS" basis,
189: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
190: // See the License for the specific language governing rights and limitations under the License.
191: //
192: // The Original Code is: all this file.
193: //
194: // The Initial Developer of the Original Code is Michael H. Kay
195: //
196: // Contributor(s):
197: //
|