поиск узла в документе org.w3c.dom через xpath принимает навсегда и возвращает ноль - PullRequest
1 голос
/ 11 июля 2011

Мой класс XpathUtility имеет следующий метод:

public Node findElementByXpath(Document doc, String axpath) throws Exception{
            XPath xPath = XPathFactory.newInstance().newXPath();
            Node node = (Node) xPath.evaluate(axpath, doc, XPathConstants.NODE);
            return node;
        }

в моем основном я загружаю документ org.w3c.dom и пытаюсь найти элемент через xpath:

XpathUtility xu = new XpathUtility();
Node foundElement= xu.findElementByXpath(domdoc, "/html[1]/body[1]/div[32]/a[1]");

Iпроверил вручную через firebug, что элемент существует с использованием этого xpath.

Что происходит при запуске этого кода: зависание становится не отвечающим примерно на 30 секунд, а затем выдает NullPointerException для foundElement.

1 Ответ

5 голосов
/ 11 июля 2011

Документ XHTML - это документ XML со ссылкой DTD, который анализаторы XML обязаны загружать и оценивать, чтобы правильно проанализировать инфо-набор XML, а элементы привязаны к пространству имен XHTML.

Итак, похоже, у вас есть две проблемы:

  1. XHTML DTD очень долго загружается с веб-сайта W3C .

    Серверы W3C медленно возвращают DTD.Является ли задержка преднамеренной?

    Да.Из-за того, что различные программные системы загружают DTD с нашего сайта миллионы раз в день (несмотря на директивы кэширования наших серверов), мы начали обслуживать DTD с нашего сайта с искусственной задержкой.Наша цель в этом состоит в том, чтобы привлечь больше внимания к нашим текущим проблемам с избыточным трафиком DTD и защитить стабильность и время отклика остальной части нашего сайта.

    Вы можете преодолеть это с использованием локального распознавателя сущностей, который загружает локальную копию DTD, вместо обращения к веб-сайту W3C при каждом запросе .

  2. Элементыв документе привязаны к пространству имен XHTML, но вы используете XPath, соответствующий стандартному пространству без имен.

    Есть несколько вещей, которые вы можете сделать, чтобы убедиться, что ваш XPath соответствует тому, чтоВы хотите :

    • Зарегистрируйте пространство имен XHTML с помощью своего механизма XPath и настройте выражения XPath для использования зарегистрированного префикса пространства имен XHTML.
    • Используйте оператор XPath, который соответствует наПространство имен XHTML и локальное имя внутри фильтра предикатов для более общего соответствия элементов, например, /*[local-name()='html' and namespace-uri()='www.w3.org/1999/xhtml/'][1]/*[local-name()='body' and namespace-uri()='www.w3.org/1999/xhtml/'][1]/*[local-name()='div' and namespace-uri()='www.w3.org/1999/xhtml/'][32]/*[local-name()='a' and namespace-uri()='www.w3.org/1999/xhtml/'][1]
    • Используйте оператор XPath, которыйподразумевает совпадения локального имени для более общего сопоставления элементов.например, /*[local-name()='html'][1]/*[local-name()='body'][1]/*[local-name()='div'][32]/*[local-name()='a'][1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...