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)

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

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

Решение Вопроса

В вашем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.

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