java - 使用 STAX API 进行 XML 解析

标签 java xml parsing openstreetmap stax

我正在尝试使用 Stax 解析开放街道 map 的 XML 结构。在我的实现中,我使用 XMLStreamConstants.START_ELEMENTXMLStreamConstants.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>

如果解析器读取Tag-Element,如何区分节点和方式?

最佳答案

您可以使用节点表示的 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/

这里是代码(try/catch 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

关于java - 使用 STAX API 进行 XML 解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19724033/

相关文章:

c - C/Unix 的参数解析助手

java - 如何在 Java 中解析字符串并查找 double

java - Jquery $.post 问题

java - 初学者数字合成器

java - 在 Spring Boot 中添加属性值的正确方法是什么

xml - 如何使用 R(Rcurl/XML 包)从 Yahoo 抓取选项数据?

javascript - 正确的 Javascript Date.parse(...) 格式字符串?

java - 使用@Cacheable注解时加载ApplicationContext失败

xml - : logback. xml 和 logback-test.xml 哪个优先?

java - 如何在不考虑 Java 命名空间名称的情况下从 XML 获取节点?