Получение дочернего узла Java - PullRequest
0 голосов
/ 08 мая 2020

У меня есть следующий код

        try {
            String xml = "<ADDITIONALIDENT><FEATURE MID=\"TEST\"><NAME>ONE NAME</NAME><VALUE>ONE VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>TWO NAME</NAME><VALUE>TWO VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>THREE NAME</NAME><VALUE>THREE VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>FOUR NAME</NAME><VALUE>FOUR VALUE</VALUE></FEATURE><FEATURE MID=\"TEST\"><NAME>FIVE NAME</NAME><VALUE>FIVE VALUE</VALUE></FEATURE></ADDITIONALIDENT>";

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            dbFactory.setNamespaceAware(true);
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document document = dBuilder.newDocument();
            document = dBuilder.parse(new InputSource(new StringReader(xml)));

            NodeList featureList = document.getElementsByTagName("FEATURE");
            for (int i = 0; i < featureList.getLength(); i++) {
                Element featureElement = (Element) featureList.item(i);
                NodeList nameList = featureElement.getElementsByTagName("NAME");
                NodeList valueList = featureElement.getElementsByTagName("VALUE");
                System.out.println("THIS IS NAME: " + nameList.item(0).getTextContent());
                System.out.println("THIS IS VALUE: " + valueList.item(0).getTextContent());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

Он отлично работает и находит правильные значения, но я не думаю, что делаю это правильно. Я чувствую, что мне не следует использовать списки внутри фактического элемента featureList.

Есть ли способ получить значения, не создавая двух списков?

<ADDITIONALIDENT>
    <FEATURE MID="TEST">
        <NAME>ONE NAME</NAME>
        <VALUE>ONE VALUE</VALUE>
    </FEATURE>
    <FEATURE MID="TEST">
        <NAME>TWO NAME</NAME>
        <VALUE>TWO VALUE</VALUE>
    </FEATURE>
<ADDITIONALIDENT>

Ответы [ 2 ]

1 голос
/ 09 мая 2020

попробуйте следующее решение,

try {
    String xml = "YOUR_XML_CONTEN";

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    dbFactory.setNamespaceAware(true);
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document document = dBuilder.newDocument();
    document = dBuilder.parse(new InputSource(new StringReader(xml)));

    NodeList featureList = document.getElementsByTagName("FEATURE");
        for (int i = 0; i < featureList.getLength(); i++) {
            Element featureElement = (Element) featureList.item(i);
            System.out.println("THIS IS NAME: " + 
            featureElement.getElementsByTagName("NAME").item(0).getTextContent());
            System.out.println("THIS IS VALUE: " + 
            featureElement.getElementsByTagName("VALUE").item(0).getTextContent());
        }
    } catch (Exception e) {
       e.printStackTrace();
}

вывод,

THIS IS NAME: ONE NAME
THIS IS VALUE: ONE VALUE
THIS IS NAME: TWO NAME
THIS IS VALUE: TWO VALUE
THIS IS NAME: THREE NAME
THIS IS VALUE: THREE VALUE
THIS IS NAME: FOUR NAME
THIS IS VALUE: FOUR VALUE
THIS IS NAME: FIVE NAME
THIS IS VALUE: FIVE VALUE
1 голос
/ 09 мая 2020

Хороший вопрос. Есть несколько способов запросить документ XML с помощью Java:

a) Разобрать документ XML в Document и использовать getElementsByTagName для извлечения нужных узлов. Это ваш нынешний подход. Это нормально для простых документов, но плохо масштабируется, потому что класс Document ничего не знает о структуре документа. Метод getElementsByTagName () должен предполагать, что любой тег, который он найдет , может встречаться более одного раза. Но вы можете исправить это ...

б) Создайте Java классов для вашей конкретной c структуры документа. Для этого у вас должна быть схема XML, которая описывает структуру вашего XML. Затем вы можете использовать JAXB для генерации классов Java для обработки вашего заданного формата c XML. В вашем примере сгенерированный код будет знать (из схемы), что в каждом теге FEATURE есть ровно один экземпляр NAME и VALUE. Методы получения для NAME и VALUE будут возвращать один узел, поэтому вашему коду не нужно будет использовать массивы для элементов с одним вхождением. См. https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html для получения дополнительной информации.

c) Используйте поддержку XPath, встроенную в Java, чтобы извлечь именно те узлы, которые вам нужны. XPath разработан для обработки XML документов и очень мощный и гибкий. Подробнее см. Как читать XML с использованием XPath в Java.

Вариант а) почти никогда не используется для обработки нетривиальных документов XML. И b), и c) очень распространены.

...