All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.xml.xpath.Jaxp13XPathTemplate Maven / Gradle / Ivy

There is a newer version: 4.0.11
Show newest version
/*
 * Copyright 2005-2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.xml.xpath;

import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathFactoryConfigurationException;

import org.springframework.util.xml.StaxUtils;
import org.springframework.xml.namespace.SimpleNamespaceContext;
import org.springframework.xml.transform.TransformerHelper;
import org.springframework.xml.transform.TraxUtils;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

/**
 * Implementation of {@link XPathOperations} that uses JAXP 1.3. JAXP 1.3 is part of Java SE since 1.5.
 * 

* Namespaces can be set using the {@code namespaces} property. * * @author Arjen Poutsma * @see #setNamespaces(java.util.Map) * @since 1.0.0 */ public class Jaxp13XPathTemplate extends AbstractXPathTemplate { private XPathFactory xpathFactory; public Jaxp13XPathTemplate() { this(XPathFactory.DEFAULT_OBJECT_MODEL_URI); } public Jaxp13XPathTemplate(String xpathFactoryUri) { try { xpathFactory = XPathFactory.newInstance(xpathFactoryUri); } catch (XPathFactoryConfigurationException ex) { throw new XPathException("Could not create XPathFactory", ex); } } @Override public boolean evaluateAsBoolean(String expression, Source context) throws XPathException { Boolean result = (Boolean) evaluate(expression, context, XPathConstants.BOOLEAN); return result != null && result; } @Override public Node evaluateAsNode(String expression, Source context) throws XPathException { return (Node) evaluate(expression, context, XPathConstants.NODE); } @Override public List evaluateAsNodeList(String expression, Source context) throws XPathException { NodeList result = (NodeList) evaluate(expression, context, XPathConstants.NODESET); List nodes = new ArrayList(result.getLength()); for (int i = 0; i < result.getLength(); i++) { nodes.add(result.item(i)); } return nodes; } @Override public double evaluateAsDouble(String expression, Source context) throws XPathException { Double result = (Double) evaluate(expression, context, XPathConstants.NUMBER); return result != null ? result : Double.NaN; } @Override public String evaluateAsString(String expression, Source context) throws XPathException { return (String) evaluate(expression, context, XPathConstants.STRING); } @Override public T evaluateAsObject(String expression, Source context, NodeMapper nodeMapper) throws XPathException { Node node = evaluateAsNode(expression, context); if (node != null) { try { return nodeMapper.mapNode(node, 0); } catch (DOMException ex) { throw new XPathException("Mapping resulted in DOMException", ex); } } else { return null; } } @Override public List evaluate(String expression, Source context, NodeMapper nodeMapper) throws XPathException { NodeList nodes = (NodeList) evaluate(expression, context, XPathConstants.NODESET); List results = new ArrayList(nodes.getLength()); for (int i = 0; i < nodes.getLength(); i++) { try { results.add(nodeMapper.mapNode(nodes.item(i), i)); } catch (DOMException ex) { throw new XPathException("Mapping resulted in DOMException", ex); } } return results; } private Object evaluate(String expression, Source context, QName returnType) throws XPathException { XPath xpath = createXPath(); if (getNamespaces() != null && !getNamespaces().isEmpty()) { SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext(); namespaceContext.setBindings(getNamespaces()); xpath.setNamespaceContext(namespaceContext); } try { EvaluationCallback callback = new EvaluationCallback(xpath, expression, returnType); TraxUtils.doWithSource(context, callback); return callback.result; } catch (javax.xml.xpath.XPathException ex) { throw new XPathException("Could not evaluate XPath expression [" + expression + "]", ex); } catch (TransformerException ex) { throw new XPathException("Could not transform context to DOM Node", ex); } catch (Exception ex) { throw new XPathException(ex.getMessage(), ex); } } private synchronized XPath createXPath() { return xpathFactory.newXPath(); } private static class EvaluationCallback implements TraxUtils.SourceCallback { private final XPath xpath; private final String expression; private final QName returnType; private final TransformerHelper transformerHelper = new TransformerHelper(); private Object result; private EvaluationCallback(XPath xpath, String expression, QName returnType) { this.xpath = xpath; this.expression = expression; this.returnType = returnType; } @Override public void domSource(Node node) throws XPathExpressionException { result = xpath.evaluate(expression, node, returnType); } @Override public void saxSource(XMLReader reader, InputSource inputSource) throws XPathExpressionException { inputSource(inputSource); } @Override public void staxSource(XMLEventReader eventReader) throws XPathExpressionException, XMLStreamException, TransformerException { Element element = getRootElement(StaxUtils.createCustomStaxSource(eventReader)); domSource(element); } @Override public void staxSource(XMLStreamReader streamReader) throws TransformerException, XPathExpressionException { Element element = getRootElement(StaxUtils.createCustomStaxSource(streamReader)); domSource(element); } @Override public void streamSource(InputStream inputStream) throws XPathExpressionException { inputSource(new InputSource(inputStream)); } @Override public void streamSource(Reader reader) throws XPathExpressionException { inputSource(new InputSource(reader)); } @Override public void source(String systemId) throws XPathExpressionException { inputSource(new InputSource(systemId)); } private void inputSource(InputSource inputSource) throws XPathExpressionException { result = xpath.evaluate(expression, inputSource, returnType); } private Element getRootElement(Source source) throws TransformerException { DOMResult domResult = new DOMResult(); transformerHelper.transform(source, domResult); Document document = (Document) domResult.getNode(); return document.getDocumentElement(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy