Все пространства имен, которые вы намереваетесь выбрать в исходном XML, должны быть связаны с префиксом на главном языке. В Java / JAXP это делается путем указания URI для каждого префикса пространства имен с использованием экземпляра javax.xml.namespace.NamespaceContext
. К сожалению, в SDK отсутствует реализация из NamespaceContext
.
К счастью, написать свою собственную очень просто:
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();
}
}
Используйте это так:
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);
Обратите внимание, что, хотя в первом пространстве имен не указан префикс в исходном документе (т. Е. Это пространство имен по умолчанию ) , вы все равно должны связать его с префиксом . Затем ваше выражение должно ссылаться на узлы в этом пространстве имен, используя выбранный вами префикс, например:
/main:workbook/main:sheets/main:sheet[1]
Имена префиксов, которые вы выбираете связать с каждым пространством имен, являются произвольными; им не нужно совпадать с тем, что появляется в исходном XML. Это отображение является лишь способом сообщить механизму XPath, что указанное имя префикса в выражении коррелирует с конкретным пространством имен в исходном документе.