Короче говоря, вам нужно предоставить NamespaceContext
вашему XPath
:
final XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
@Override
public Iterator<String> getPrefixes(final String namespaceURI) {
return null;
}
@Override
public String getPrefix(final String namespaceURI) {
return null;
}
@Override
public String getNamespaceURI(final String prefix) {
return "http://c1.net.corbis.com/";
}
});
final NodeList list = (NodeList) xPath.evaluate("//c:URL128/@Value", source, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
System.out.println(list.item(i).getTextContent());
}
Кажется, что единственный метод, который XPath требует от нас в этом случае реализоватьis getNamespaceURI(String prefix)
.
Обратите внимание, что фактический префикс в "c: URL128" на самом деле не имеет значения - вы могли бы так же легко использовать ": URL128".Когда у вас do есть несколько пространств имен в вашем XML, становится важно различать их (используя Map
или серию if-then-else
, если относительно мало элементов).
Если выне можете или не хотите жестко кодировать префиксы, которые вы можете сами извлечь из XML-документа, но для этого требуется немного больше кода ...
См. также в этом сообщении длябольше деталей.