Android 简单的 XML 反序列化

Android SimpleXML Deserialisation

我正在尝试从这个 graphml 创建节点和边缘对象。我有一些很好的建议告诉我使用几个包,在进一步研究中,它是一个 android 实现,我选择了简单 xml.

http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#nested

我从节点开始。我已经创建了我的节点 class:

@Root(name="node")
public class DeserialisedNode implements Serializable {

    public DeserialisedNode() {
        super();
    }

    @Attribute(name = "id")
    private int iD;

    private String venueId;
    @Element(name = "name")
    private String name;
    @Element(name = "waypoint_type")
    private String type;
    @Element(name = "lat")
    private double latitude;
    @Element(name = "lon")
    private double longitude;
    @Element(name = "level_id")
    private int levelId;
    @Element(name = "on_starting_route")
    private String onStartingRoute;
    @Element(name = "on_finish_route")
    private String onFinishRoute;


    public DeserialisedNode(int iD, String name, String type, double latitude, double longitude, int levelId, String onStartingRoute, String onFinishRoute) {
        this.iD = iD;
        this.name = name;
        this.type = type;
        this.latitude = latitude;
        this.longitude = longitude;
        this.levelId = levelId;
        this.onStartingRoute = onStartingRoute;
        this.onFinishRoute = onFinishRoute;
    }
}

在我的 mainActivity 中我添加了:

 try {
            Serializer serializer = new Persister();
            AssetManager assetManager = getAssets();
            InputStream inputStream = assetManager.open("routing.xml");
            DeserialisedNode node = serializer.read(DeserialisedNode.class, inputStream);
            System.out.println("It worked! "+node.getClass().getName());
            System.out.println("It worked! "+node.getClass().getName());
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("error! "+e.getMessage());
        }

开始的例子xml:

<?xml version='1.0' encoding='utf-8'?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
  <key attr.name="weight" attr.type="double" for="edge" id="weight" />
  <key attr.name="edgeid" attr.type="string" for="edge" id="edgeid" />
  <key attr.name="alpha" attr.type="string" for="edge" id="alpha" />
  <key attr.name="intendedpathlonlat" attr.type="string" for="edge" id="intendedpathlonlat" />
  <key attr.name="levelid" attr.type="string" for="edge" id="levelid" />
  <key attr.name="weight" attr.type="long" for="edge" id="weight" />
  <key attr.name="type" attr.type="string" for="edge" id="type" />
  <key attr.name="relatedroutes" attr.type="string" for="node" id="relatedroutes" />
  <key attr.name="description" attr.type="string" for="node" id="description" />
  <key attr.name="title" attr.type="string" for="node" id="title" />
  <key attr.name="on_finish_route" attr.type="string" for="node" id="on_finish_route" />
  <key attr.name="on_starting_route" attr.type="string" for="node" id="on_starting_route" />
  <key attr.name="level_id" attr.type="string" for="node" id="level_id" />
  <key attr.name="waypoint_type" attr.type="string" for="node" id="waypoint_type" />
  <key attr.name="name" attr.type="string" for="node" id="name" />
  <key attr.name="lon" attr.type="string" for="node" id="lon" />
  <key attr.name="lat" attr.type="string" for="node" id="lat" />
  <graph edgedefault="directed" id="new id here">
    <node id="L08-022">
      <data key="lat">30.69330963</data>
      <data key="lon">-53.98752537</data>
      <data key="name" />
      <data key="waypoint_type">escalator</data>
      <data key="level_id">1080000</data>
      <data key="on_starting_route" />
      <data key="on_finish_route" />
    </node>
    <node id="L08-023">
      <data key="lat">30.69318355</data>
      <data key="lon">-53.98755793</data>
      <data key="name" />
      <data key="waypoint_type">stairs</data>
      <data key="level_id">1080000</data>
      <data key="on_starting_route" />
      <data key="on_finish_route" />
    </node>
etc......

我的错误是:

W/System.err: org.simpleframework.xml.core.AttributeException: Attribute 'schemaLocation' does not have a match in class com.app.model.maps.DeserialisedNode at line 2

我需要取出节点和边缘数据。

Java SimpleXML 库看起来主要用于将 Java 对象序列化为 XML。它确实支持反序列化(将 XML 解析为 Java)——但是 documentation 表示:

org.simpleframework.xml.stream - Provides an XML parsing layer over a set of third party libraries. The stream package provides an event based XML parsing framework that can be used with several third party libraries such as DOM, StAX and the XML pull API.

换句话说,它委托给其他包。

因此,这是一种 StAX 方法。这使用基于游标的 StAX XML Stream Reader(不是替代 StAX 事件 reader),因为正如 "Comparing Cursor and Iterator APIs" 部分中所说的 here

If you are programming for a particularly memory-constrained environment, like Java ME, you can make smaller, more efficient code with the cursor API.

这是方法。它只是解析输入文件并打印出相关部分。它不会尝试做更多的事情 - 只是为了演示如何访问您需要的数据项:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;

...

private final String fileNameString = "C:/tmp/files/graphml.xml";

public void read() throws XMLStreamException, FileNotFoundException {
    XMLInputFactory xmlif = XMLInputFactory.newInstance();
    XMLStreamReader xmlr = xmlif.createXMLStreamReader(fileNameString,
            new FileInputStream(fileNameString));

    while (xmlr.hasNext()) {
        int eventType = xmlr.next();

        if (eventType == XMLEvent.START_ELEMENT) {
            if (xmlr.getLocalName().equals("node")) {
                if (xmlr.getAttributeCount() == 1) { // a safety check
                    String nodeID = xmlr.getAttributeValue(0);
                    System.out.println("---");
                    System.out.println("Node ID: " + nodeID);
                }
            }
            if (xmlr.getLocalName().equals("data")) {
                if (xmlr.getAttributeCount() == 1) { // a safety check
                    String dataKey = xmlr.getAttributeValue(0);
                    String dataValue = xmlr.getElementText();
                    System.out.println("Data key: " + dataKey + " Data value: " + dataValue);
                }
            }
        }
    }
}

关键部分是 XMLStreamReader 对象,它使您可以轻松访问每个标签的文本内容及其属性。

根据 SimpleXML 规范,应该可以在 SimpleXML 中使用它 - 但我没有尝试过。或者,也许您可​​以完全不使用 SimpleXML 而只使用 StAX。

在我的例子中,这将打印以下输出:

Node ID: L08-022
Data key: lat Data value: 40.69330963
Data key: lon Data value: -73.98752537
Data key: name Data value: 
Data key: waypoint_type Data value: escalator
Data key: level_id Data value: 1080000
Data key: on_starting_route Data value: 
Data key: on_finish_route Data value: 
---
Node ID: L08-023
Data key: lat Data value: 40.69318355
Data key: lon Data value: -73.98755793
Data key: name Data value: 
Data key: waypoint_type Data value: stairs
Data key: level_id Data value: 1080000
Data key: on_starting_route Data value: 
Data key: on_finish_route Data value: 
---
Node ID: L08-024
Data key: lat Data value: 40.69316844
Data key: lon Data value: -73.98755873
Data key: name Data value: 
Data key: waypoint_type Data value: stairs
Data key: level_id Data value: 1080000
Data key: on_starting_route Data value: 
Data key: on_finish_route Data value: 

我使用的示例文件是这样的:

<?xml version='1.0' encoding='utf-8'?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key attr.name="weight" attr.type="double" for="edge" id="weight" />
  <key attr.name="edgeid" attr.type="string" for="edge" id="edgeid" />
  <key attr.name="alpha" attr.type="string" for="edge" id="alpha" />
  <key attr.name="intendedpathlonlat" attr.type="string" for="edge" id="intendedpathlonlat" />
  <key attr.name="levelid" attr.type="string" for="edge" id="levelid" />
  <key attr.name="weight" attr.type="long" for="edge" id="weight" />
  <key attr.name="type" attr.type="string" for="edge" id="type" />
  <key attr.name="relatedroutes" attr.type="string" for="node" id="relatedroutes" />
  <key attr.name="description" attr.type="string" for="node" id="description" />
  <key attr.name="title" attr.type="string" for="node" id="title" />
  <key attr.name="on_finish_route" attr.type="string" for="node" id="on_finish_route" />
  <key attr.name="on_starting_route" attr.type="string" for="node" id="on_starting_route" />
  <key attr.name="level_id" attr.type="string" for="node" id="level_id" />
  <key attr.name="waypoint_type" attr.type="string" for="node" id="waypoint_type" />
  <key attr.name="name" attr.type="string" for="node" id="name" />
  <key attr.name="lon" attr.type="string" for="node" id="lon" />
  <key attr.name="lat" attr.type="string" for="node" id="lat" />
  <graph edgedefault="directed" id="new id here">
    <node id="L08-022">
      <data key="lat">40.69330963</data>
      <data key="lon">-73.98752537</data>
      <data key="name" />
      <data key="waypoint_type">escalator</data>
      <data key="level_id">1080000</data>
      <data key="on_starting_route" />
      <data key="on_finish_route" />
    </node>
    <node id="L08-023">
      <data key="lat">40.69318355</data>
      <data key="lon">-73.98755793</data>
      <data key="name" />
      <data key="waypoint_type">stairs</data>
      <data key="level_id">1080000</data>
      <data key="on_starting_route" />
      <data key="on_finish_route" />
    </node>
    <node id="L08-024">
      <data key="lat">40.69316844</data>
      <data key="lon">-73.98755873</data>
      <data key="name" />
      <data key="waypoint_type">stairs</data>
      <data key="level_id">1080000</data>
      <data key="on_starting_route" />
      <data key="on_finish_route" />
    </node>
  </graph>
</graphml>