/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2009-2011, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotools.util;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Scanner;
import org.apache.commons.jxpath.JXPathContext;
import org.jdom.Document;
import org.xml.sax.helpers.NamespaceSupport;
/**
* Ulities class for xpath handling on a jdom document object
*
* @author Russell Petty (GeoScience Victoria)
* @version $Id$
*
*
* @source $URL$
*/
public class XmlXpathUtilites {
/**
* @param ns namespaces
* @param xpathString xpath to search on
* @param doc xml to search
* @return a list of values matching the xpath in the xml supplied
*/
public static List<String> getXPathValues(NamespaceSupport ns, String xpathString, Document doc) {
JXPathContext context = initialiseContext(ns, doc);
return getXPathValues(xpathString, context);
}
/**
* @param ns namespaces
* @param xpathString xpath to search on
* @param doc xml to search
* @return count of the values matching the xpath passed in
*/
public static int countXPathNodes(NamespaceSupport ns, String xpathString, Document doc) {
int count = 0;
List<String> ls = getXPathValues(ns, xpathString, doc);
if (ls != null) {
count = ls.size();
}
return count;
}
/**
*
* @param ns namespaces
* @param xpathString xpath to search on
* @param doc xml to search
* @return the (single) value matching the xpath in the xml supplied
*/
public static String getSingleXPathValue(NamespaceSupport ns, String xpathString, Document doc) {
String id = null;
JXPathContext context = initialiseContext(ns, doc);
try {
Object ob = context.getValue(xpathString);
id = (String) ob;
} catch (RuntimeException e) {
throw new RuntimeException("Error reading xpath " + xpathString, e);
}
return id;
}
private static JXPathContext initialiseContext(NamespaceSupport ns, Document doc) {
JXPathContext context = JXPathContext.newContext(doc);
addNamespaces(ns, context);
context.setLenient(true);
return context;
}
private static void addNamespaces(NamespaceSupport ns, JXPathContext context) {
Enumeration<String> prefixes = ns.getPrefixes();
while (prefixes.hasMoreElements()) {
String prefix = prefixes.nextElement();
String uri = ns.getURI(prefix);
context.registerNamespace(prefix, uri);
}
}
/**
* Remove indexes from an xpath string.
* @param xpath xpath string
* @return unindexed xpath string
*/
public static String removeIndexes(String xpath) {
final String[] partialSteps = xpath.split("[/]");
if (partialSteps.length == 0) {
return xpath;
}
int startIndex = 0;
StringBuffer buf = new StringBuffer();
for (int i = startIndex; i < partialSteps.length; i++) {
String step = partialSteps[i];
int start = step.indexOf('[');
if (start > -1) {
int end = step.indexOf(']');
Scanner scanner = new Scanner(step.substring(start + 1, end));
if (scanner.hasNextInt()) {
// remove index and the brackets
step = step.substring(0, start);
}
}
buf.append(step);
if (i < partialSteps.length - 1) {
buf.append("/");
}
}
return buf.toString();
}
private static List<String> getXPathValues(String xpathString, JXPathContext context) {
List values = null;
try {
values = context.selectNodes(xpathString);
} catch (RuntimeException e) {
throw new RuntimeException("Error reading xpath " + xpathString, e);
}
List<String> ls = null;
if(values == null) {
ls = new ArrayList<String>();
} else {
ls = new ArrayList<String>(values.size());
for (int i = 0; i < values.size(); i++) {
Object value = values.get(i);
String unwrappedValue = "";
if (value instanceof org.jdom.Attribute) {
unwrappedValue = ((org.jdom.Attribute) value).getValue();
} else if (value instanceof org.jdom.Element) {
unwrappedValue = ((org.jdom.Element) value).getValue();
}
ls.add(unwrappedValue);
}
}
return ls;
}
}