All namespaces that you intend to select from the source XML must be prefixed in the host language. In Java / JAXP, this is done by specifying a URI for each namespace prefix using an instance of javax.xml.namespace.NamespaceContext . Unfortunately, the SDK does not have a NamespaceContext implementation .
Fortunately, it's very easy to write your own:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.namespace.NamespaceContext; public class SimpleNamespaceContext implements NamespaceContext { private final Map<String, String> PREF_MAP = new HashMap<String, String>(); public SimpleNamespaceContext(final Map<String, String> prefMap) { PREF_MAP.putAll(prefMap); } public String getNamespaceURI(String prefix) { return PREF_MAP.get(prefix); } public String getPrefix(String uri) { throw new UnsupportedOperationException(); } public Iterator getPrefixes(String uri) { throw new UnsupportedOperationException(); } }
Use it as follows:
XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); HashMap<String, String> prefMap = new HashMap<String, String>() {{ put("main", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); put("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"); }}; SimpleNamespaceContext namespaces = new SimpleNamespaceContext(prefMap); xpath.setNamespaceContext(namespaces); XPathExpression expr = xpath .compile("/main:workbook/main:sheets/main:sheet[1]"); Object result = expr.evaluate(doc, XPathConstants.NODESET);
Note that although the first namespace does not specify a prefix in the source document (i.e. this is the default namespace ), you should still associate it with the prefix. Your expression should then refer to the nodes in this namespace using the prefix you selected, for example:
/main:workbook/main:sheets/main:sheet[1]
The prefix names that you want to associate with each namespace are arbitrary; they donβt need to map what appears in the source XML. This mapping is just a way to tell the XPath engine that a given prefix name in an expression correlates with a specific namespace in the source document.
Wayne Burkett Jun 17 '11 at 23:11 2011-06-17 23:11
source share