Nano Hash - криптовалюты, майнинг, программирование

Как использовать пространство имен по умолчанию в выражениях dom4j selectNotes xpath?

Я использую Dom4J для анализа некоторых файлов Maven Pom. Когда я использую файлы Pom без пространства имен по умолчанию, все работает нормально. Например:

Document pom = DocumentHelper.parseText(
                 "<project>" +
                 "   <groupId>xx.gov.xxx.sistema.xxx</groupId>" + 
                 "   <artifactId>sis-teste</artifactId>" + 
                 "   <packaging>war</packaging>" + 
                 "</project>");
//below works fine
String groupId = pom.selectSingleNode("/project/groupId").getText()

Но если мой файл Pom определяет пространство имен по умолчанию, он перестает работать:

Document pom = DocumentHelper.parseText(
                 "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">" +
                 "   <groupId>xx.gov.xxx.sistema.xxx</groupId>" + 
                 "   <artifactId>sis-teste</artifactId>" + 
                 "   <packaging>war</packaging>" + 
                 "</project>");
//NullPointerException!!!!!!!!!!!!!!!!!!!!
String groupId = pom.selectSingleNode("/project/groupId").getText()

Странно то, что pom.selectSingleNode("/project") работает нормально.

Как заставить мой запрос xpath работать с пространством имен по умолчанию? Я хочу запросить только "/project/groupId"и получить узел groupId.


  • Если вы не хотите менять свой запрос, вам придется погрузиться в кроличью нору пространств имен в XPath. Я предлагаю вам прочитать это edankert.com/defaultnamespaces.html 10.02.2018

Ответы:


1

Вот так:

    Document pom = DocumentHelper.parseText(
            "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">" +
            "   <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
            "   <artifactId>sis-teste</artifactId>" +
            "   <packaging>war</packaging>" +
            "</project>");
    Map<String, String> nsContext = new HashMap<>();
    nsContext.put("p", "http://maven.apache.org/POM/4.0.0");
    XPath xp = pom.createXPath("/p:project/p:groupId");
    xp.setNamespaceURIs(nsContext);
    String groupId = xp.selectSingleNode(pom).getText();
    System.out.println(groupId);

ОБНОВЛЕНИЕ

После более внимательного изучения кода DOM4J это возможно, если вы можете допустить установку карты URI глобального пространства имен:

    Map<String, String> nsContext = new HashMap<>();
    nsContext.put("p", "http://maven.apache.org/POM/4.0.0");
    DocumentFactory.getInstance().setXPathNamespaceURIs(nsContext);

    Document pom = DocumentHelper.parseText(
            "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">" +
            "   <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
            "   <artifactId>sis-teste</artifactId>" +
            "   <packaging>war</packaging>" +
            "</project>");
    String groupId = pom.selectSingleNode("/p:project/p:groupId").getText();
    System.out.println(groupId);

Более локализованным решением было бы использовать SAXReader и настроить его с помощью специализированного DocumentFactory, а не глобального.

12.02.2018
  • Это правильный ответ - использовать xpaths с пространствами имен, но это заставляет меня изменить все выражения xpath и все вызовы API. Похоже, что нет возможности выбрать пространство имен при выборе непосредственно в объекте Document. 15.02.2018

  • 2

    Мое хакерское решение состояло в том, чтобы просто удалить пространство имен файла pom перед созданием объекта Dom. Не очень красиво, но работает нормально и жизнь продолжается.

    05.04.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..