Как разобрать xml и получить соответствующие значения с помощью Stax Iterator? - PullRequest
0 голосов
/ 27 августа 2018

Я хотел бы проанализировать xml-узел, используя STAX Iterator API, и получить значения каждого id-узла.В приведенном ниже коде, как я могу получить соответствующее значение типа id = id2 или id3.Как я могу это сделать?

<entity>
   <id type="id1">8500123</id>
   <id type="id2">8500124</id>
   <id type="id3">8500125</id>
   <link idType="someId">99369</link>
 </entity>

Код API STAX Iterator ниже;

XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream(fileName));
    while (xmlEventReader.hasNext()) {
        XMLEvent xmlEvent = xmlEventReader.nextEvent();
        if (xmlEvent.isStartElement()) {
            StartElement startElement = xmlEvent.asStartElement();
            if (startElement.getName().getLocalPart().equals("entity")) {
                XMLEvent xmlEvent2 = xmlEventReader.nextEvent();//has to forgo this bcoz it always return a new line.
                XMLEvent xmlEvent3 = xmlEventReader.nextEvent();
                if (xmlEvent3.isStartElement()) {
                    StartElement startElement2 = xmlEvent3.asStartElement();
                    if (startElement2.getName().getLocalPart().equals("id")) {
                        connector = new Connector();
                        Attribute idAttr = startElement2.getAttributeByName(new QName("type"));
                        if(idAttr.getName().equals("id1")){
                            connector.setId1(idAttr.getValue());
                        }
                    }
                }
            }
        }
    } 

1 Ответ

0 голосов
/ 27 января 2019

Поскольку вопрос старый, вероятно, проблема больше не существует, но я просто пытался сделать то же самое.Пример кода был почти там;отсутствующим шагом была проверка типа события XMLStreamConstants.CHARACTERS, который соответствует либо:

  • данных между открывающим и закрывающим тегом.
  • Пробел между тегами.

Таким образом, в вашем случае вы хотите извлечь данные только при соблюдении всех этих условий:

  • Тип обрабатываемого события: XMLStreamConstants.CHARACTERS (в этом случае EventType.isCharacters()возвращает истину).
  • Обработанное непосредственно предшествующее событие имело тип XMLStreamConstants.START_ELEMENT.
  • Значением атрибута type этого предшествующего начального элемента было "id2" или "id3".

Это можно сделать путем настройки существующего кода, но более чистый и более общий подход состоит в том, чтобы итеративно обрабатывать события, возвращаемые XMLEventReader, с помощью оператора case.Чтобы получить значение данных между начальным тегом и конечным тегом:

Characters characters = xmlEvent.asCharacters();
String data = characters.getData();

Вот рабочий пример, где файл sample.xml содержит данные в OP:

package pkg;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StaxDemo {

    public static void main(String[] args) throws XMLStreamException, IOException {

        try (Reader reader = new FileReader("sample.xml");) {
            XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
            XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(reader);
            parseXml(xmlEventReader);
        }
    }

    static void parseXml(XMLEventReader xmlEventReader) throws XMLStreamException {

        String typeValue = null;

        while (xmlEventReader.hasNext()) {
            XMLEvent xmlEvent = xmlEventReader.nextEvent();
            switch (xmlEvent.getEventType()) {

            case XMLStreamConstants.START_DOCUMENT:
                System.out.println("XMLEvent.START_DOCUMENT");
                break;

            case XMLStreamConstants.START_ELEMENT:
                StartElement startElement = xmlEvent.asStartElement();
                Attribute typeAttribute = startElement.getAttributeByName(new QName("type"));
                if (typeAttribute != null) {
                    typeValue = typeAttribute.getValue();
                }
                System.out.println("XMLEvent.START_ELEMENT: <" + startElement.getName() + "> " + "type=" + typeValue);
                break;

            case XMLStreamConstants.CHARACTERS:
                Characters characters = xmlEvent.asCharacters();
                if ((typeValue != null)) { // Non-null if preceding event was for START_ELEMENT.
                    if ((typeValue.equals("id2")) || (typeValue.equals("id3"))) {
                        String data = characters.getData();
                        System.out.println("XMLEvent.CHARACTERS:    data=[" + data + "]");
                    }
                    typeValue = null;
                }
                break;

            case XMLStreamConstants.END_ELEMENT:
                EndElement endElement = xmlEvent.asEndElement();
                System.out.println("XMLEvent.END_ELEMENT:   </" + endElement.getName() + ">");
                break;

            case XMLStreamConstants.END_DOCUMENT:
                System.out.println("XMLEvent.END_DOCUMENT");
                break;

            default:
                System.out.println("case default: Event Type = " + xmlEvent.getEventType());
                break;
            }
        }
    }
}

Я добавил несколько вызовов println(), чтобы просто уточнить, как файл обрабатывается XMLEventReader.Вот вывод:

XMLEvent.START_DOCUMENT
XMLEvent.START_ELEMENT: <entity> type=null
XMLEvent.START_ELEMENT: <id> type=id1
XMLEvent.END_ELEMENT:   </id>
XMLEvent.START_ELEMENT: <id> type=id2
XMLEvent.CHARACTERS:    data=[z8500124]
XMLEvent.END_ELEMENT:   </id>
XMLEvent.START_ELEMENT: <id> type=id3
XMLEvent.CHARACTERS:    data=[z8500125]
XMLEvent.END_ELEMENT:   </id>
XMLEvent.START_ELEMENT: <link> type=null
XMLEvent.END_ELEMENT:   </link>
XMLEvent.END_ELEMENT:   </entity>
XMLEvent.END_DOCUMENT

Oracle предоставляет учебник для StAX .Пока есть вся основная информация, я нашел ее немного неорганизованной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...