Разбор XML с помощью STAX API

Я пытаюсь разобрать XML-структуру карт открытых улиц с помощью Stax. В моей реализации я использую XMLStreamConstants.START_ELEMENT и XMLStreamConstants.END_ELEMENT для распознавания элементов.

В структуре OpenStreetMaps есть такие элементы, как тег, которые описывают как узел, так и путь. Вот пример структуры:

      <node id="2311741639" ... lat="50.7756648" lon="6.0844948">
       <tag k="entrance" v="yes"/>
      </node>
      <way id="4964449" visible="true" ... uid="67862">
       <nd ref="27290865"/>
        ...
       <tag k="highway" v="residential"/>
        ...
      </way>

Как я могу отличить узел от пути, если синтаксический анализатор читает элемент тега?


person Pamp    schedule 01.11.2013    source источник


Ответы (1)


Вы можете использовать ArrayDeque ваших представлений узлов или даже построить временную структуру, подобную DOM, если глубина вашей иерархии невелика.

Вот пример с ArrayDeque...

Предполагая, что этот файл XML с именем stuff.xml:

<?xml version="1.0" encoding="UTF-8"?>

<stuff>

<node id="2311741639" lat="50.7756648" lon="6.0844948">
    <tag k="entrance" v="yes"/>
</node>

<way id="4964449" visible="true" uid="67862">
    <nd ref="27290865"/>
    <tag k="highway" v="residential"/>
</way>

</stuff>

Предполагая, что файл находится по пути: /my/path/

Вот код (попробуйте/поймайте стиль Java 6):

InputStream is = null;
XMLStreamReader reader = null;
try {
    is = new FileInputStream(new File("/my/path/stuff.xml"));
    XMLInputFactory xif = XMLInputFactory.newInstance();
    reader = xif.createXMLStreamReader(is);
    ArrayDeque<String> nodes = new ArrayDeque<String>();
    while (reader.hasNext()) {
        int current = reader.next();
        switch (current) {
            case XMLStreamConstants.START_ELEMENT: {
                nodes.add(reader.getLocalName());
                System.out.println("START: " + nodes.getLast());
                if (nodes.size() > 1) {
                    Iterator<String> iterator = nodes.descendingIterator();
                    // skipping first one as it's already represented
                    iterator.next();
                    while (iterator.hasNext()) {
                        System.out.println("\t in " + iterator.next());
                    }
                }
                break;
            }
            case XMLStreamConstants.END_ELEMENT: {
                System.out.println("END: " + nodes.removeLast());
                Iterator<String> iterator = nodes.descendingIterator();
                while (iterator.hasNext()) {
                    System.out.println("\t in " + iterator.next());
                }
                break;
            }
        }
    }

}
        catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace();
        }
        catch (XMLStreamException xse) {
            xse.printStackTrace();
        }
        finally {
            if (reader != null) {
                try {
                    reader.close();
                    is.close();
                }
                catch (XMLStreamException xse) {
                    xse.printStackTrace();
                }
                catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }

Выход:

START: stuff
START: node
     in stuff
START: tag
     in node
     in stuff
END: tag
     in node
     in stuff
END: node
     in stuff
START: way
     in stuff
START: nd
     in way
     in stuff
END: nd
     in way
     in stuff
START: tag
     in way
     in stuff
END: tag
     in way
     in stuff
END: way
     in stuff
END: stuff
person Mena    schedule 01.11.2013