Как написать XPath для получения значения атрибута узла из "пространства имен XML" в Java - PullRequest
1 голос
/ 21 февраля 2020

INPUT_ XML:

<?xml version="1.0" encoding="UTF-8">
<root xmlns:ns1="http://path1/schema1" xmlns:ns2="http://path2/schema2">
    <ns1:abc>1234</ns1:abc>
    <ns2:def>5678</ns2:def>
</root>

В Java я пытаюсь написать выражение XPath, которое получит значение, соответствующее этому атрибуту "xmlns: ns1", из указанного выше INPUT_ XML содержимое строки.

Я пробовал следующее:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(INPUT_XML);

    String xpathExpression = "/root/xmlns:ns1";

    // Create XPathFactory object
    XPathFactory xpathFactory = XPathFactory.newInstance();

    // Create XPath object
    XPath xpath = xpathFactory.newXPath();

    // Create XPathExpression object
    XPathExpression expr = xpath.compile(xpathExpression);

    // Evaluate expression result on XML document
    NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue());
    }

Но приведенный выше код не дает ожидаемое значение указанного атрибута, т.е. xmlns: ns1 . Я сильно подозреваю, что xPathExpression неправильно. Пожалуйста, предложите правильное выражение XPath или правильный подход к решению этой проблемы.

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Если вы используете процессор XPath 1.0 или процессор XPath 2.0 с включенным режимом совместимости XPath 1.0, вы можете использовать ось namespace для выбора значения пространства имен.

Вам потребуется внесите следующие изменения в свой код:

String xpathExpression = "/root/namespace::ns1"
0 голосов
/ 21 февраля 2020

xmlns:ns1="http://path1/schema1" и xmlns:ns2="http://path2/schema2" являются не атрибутами, а объявлениями пространства имен . Вы не можете получить их с помощью объявления XPath так легко (для этого есть функция nameathace-uri () функции XPath, но элемент root не имеет пространства имен, он определяет их только для будущего использования).

При использовании DOM API вы можете использовать метод lookupNamespaceURI ():

System.out.println("ns1 = " + doc.getDocumentElement().lookupNamespaceURI("ns1"));
System.out.println("ns2 = " + doc.getDocumentElement().lookupNamespaceURI("ns2"));

При использовании XPath вы можете попробовать следующие выражения:

namespace-uri(/*[local-name()='root']/*[local-name()='abc'])
namespace-uri(/*[local-name()='root']/*[local-name()='def'])
...