Java XPath: запросы с пространством имен по умолчанию xmlns

Я хочу сделать запрос XPath для этого файла (показана выдержка):

<?xml version="1.0" encoding="UTF-8"?>
<!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST -->
<ModelClass xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.ModelClass:2.0">
    <ModelClass.Parent>
        <Core.Reference package="com.test.mypackage" name="ModelName" type="Model"/>

Это фрагмент кода, который я использую:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document document = builder.parse(new File(testFile));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
...

String result = xpath.evaluate(xpathQueryString, document);
System.out.println(result);

Проблема, с которой я сталкиваюсь, состоит в том, что, когда на пространство имен по умолчанию ссылаются в запросе XPath, метод getNamespaceURI не вызывается для его разрешения. Этот запрос, например, ничего не извлекает:

//xmlns:ModelClass.Parent/xmlns:Core.Reference[@type=\"Model\"]/@package

Теперь я "попробовал" обмануть " парсер, заменивxmlns с фальшивым префиксомd а затем писатьgetNamespaceURI метод соответственно (чтобы вернутьhttp://xml.sap.com/2002/10/metamodel/webdynpro когдаd встречается). В этом случаеgetNamespaceURI вызывается, но результатом вычисления выражения XPath всегда является пустая строка.

Если я удаляю пространства имен из файла и из выражения запроса XPath, я могу получить нужную строку (com.test.mypackage).

Есть ли способ заставить вещи работать должным образом с пространством имен по умолчанию?

Ответы на вопрос(2)

чтобы «без префикса означало отсутствие пространства имен». Таким образом, JAXP, который был разработан для XPath 1.0, совершенно правильно, чтобы остановить привязку «нулевого префикса». в некоторое ненулевое пространство имен.

XPath 2.0 позволяет вам объявлять пространство имен по умолчанию для неквалифицированных имен в вашем выражении XPath, но для того, чтобы воспользоваться этим, вам потребуется API (например, S9api Saxon), который использует эту функцию.

 Pietro M.24 мая 2012 г., 10:37
Спасибо Майкл за дополнительную информацию.
Решение Вопроса

Namespace контекст, привязать префикс по вашему выбору (например,df) к URI пространства имен в документе

xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro";
        ...
       }
    });

и затем используйте этот префикс в ваших выражениях пути для определения имен элементов, например,/df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package.

 Pietro M.23 мая 2012 г., 16:13
Это добилось цели. Я думал, что DocumentBuilder по умолчанию знает о пространствах имен. Еще раз спасибо
 23 мая 2012 г., 16:08
Убедитесь, что вы также создаете DocumentBuilder с поддержкой пространства именdocs.oracle.com/javase/6/docs/api/javax/xml/parsers/… перед работой с пространствами имен.
 Pietro M.23 мая 2012 г., 15:52
Привет, Мартин, я попробовал, но это не работает ...

Ваш ответ на вопрос