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

org.daisy.pipeline.client.utils.XPath Maven / Gradle / Ivy

There is a newer version: 5.0.1
Show newest version
package org.daisy.pipeline.client.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.daisy.pipeline.client.Pipeline2Exception;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Utility class for querying XML documents using XPath.
 */
public class XPath {
	
	/** Default namespace for the Pipeline 2 Web API. */
	public static final Map dp2ns; 
	static {
    	Map nsMap = new HashMap();
    	nsMap.put("xml", "http://www.w3.org/XML/1998/namespace");
    	nsMap.put("d", "http://www.daisy.org/ns/pipeline/data");
    	dp2ns = Collections.unmodifiableMap(nsMap);
	}
	
	private static Map expressions = new HashMap();
	public Map namespaces = new HashMap();
	private static NamespaceContextMap nsContext = new NamespaceContextMap();
	
	private XPath() {}
	
	private static XPathExpression xpath(String expression, Map ns) throws XPathExpressionException {
		updateNs(ns);
		if (expressions.containsKey(expression)) {
			return expressions.get(expression);
		} else {
			javax.xml.xpath.XPath xpath = XPathFactory.newInstance().newXPath();
			xpath.setNamespaceContext(nsContext);
			XPathExpression compiledExpression = xpath.compile(expression);
			expressions.put(expression, compiledExpression);
			return compiledExpression;
		}
	}
	
	private static void updateNs(Map ns) {
		boolean equals = ns.size() == nsContext.getMap().size()-2;
		if (equals) {
			for (String prefix : ns.keySet()) {
				if (!nsContext.getMap().containsKey(prefix) || !nsContext.getMap().get(prefix).equals(ns.get(prefix))) {
					equals = false;
					break;
				}
			}
		}
		if (!equals) {
			nsContext = new NamespaceContextMap(ns);
			expressions.clear();
		}
	}
	
	/**
	 * Select all nodes matching `expr` and return them as a List.
	 * 
	 * @param expr XPath expression
	 * @param doc XML node
	 * @param ns Namespace map ({@code Map })
	 * @return A list containing all the matching nodes
	 * @throws Pipeline2Exception thrown when an error occurs
	 */
	public static List selectNodes(String expr, Node doc, Map ns) throws Pipeline2Exception {
		if (doc == null || expr == null)
			return new ArrayList();
		
		try {
			NodeList nodeList = (NodeList) xpath(expr,ns).evaluate(doc, XPathConstants.NODESET);
			List result = new ArrayList();
		    for (int i = 0; i < nodeList.getLength(); i++) {
		    	result.add(nodeList.item(i));
		    }
		    return result;
			
		} catch (XPathExpressionException e) {
			throw new Pipeline2Exception(e);
		}
	}
	
	/**
	 * Select the node matching `expr` and return its text content.
	 * 
	 * @param expr XPath expression
	 * @param doc XML node
	 * @param ns Namespace map ({@code Map })
	 * @return The text content
	 * @throws Pipeline2Exception thrown when an error occurs
	 */
	public static String selectText(String expr, Node doc, Map ns) throws Pipeline2Exception {
		if (doc == null || expr == null)
			return null;
		
		try {
			if (((NodeList)xpath(expr,ns).evaluate(doc, XPathConstants.NODESET)).getLength() == 0) {
				return null;
				
			} else {
				String nodeText = (String) xpath(expr,ns).evaluate(doc, XPathConstants.STRING);
				return nodeText;
			}
			
		} catch (XPathExpressionException e) {
			e.printStackTrace();
			throw new Pipeline2Exception(e);
		}
	}
	
	/**
	 * Select the nodes matching `expr` and return it.
	 * 
	 * @param expr XPath expression
	 * @param doc XML node
	 * @param ns Namespace map ({@code Map })
	 * @return The matching node
	 * @throws Pipeline2Exception thrown when an error occurs
	 */
	public static Node selectNode(String expr, Node doc, Map ns) throws Pipeline2Exception {
		if (doc == null || expr == null)
			return null;
		
		try {
			NodeList nodeList = (NodeList) xpath(expr,ns).evaluate(doc, XPathConstants.NODESET);
			if (nodeList.getLength() == 0) return null;
			else return nodeList.item(0);
			
		} catch (XPathExpressionException e) {
			e.printStackTrace();
			throw new Pipeline2Exception(e);
		}
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy