【问题标题】:Android SimpleXML DeserialisationAndroid 简单 XML 反序列化
【发布时间】:2020-07-10 06:46:34
【问题描述】:

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

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

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

@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 android xml xml-deserialization simple-framework


    【解决方案1】:

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

    org.simpleframework.xml.stream - 在一组第三方库上提供 XML 解析层。流包提供了一个基于事件的 XML 解析框架,可以与多个第三方库(如 DOM、StAX 和 XML pull API)一起使用。

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

    所以,这是一种 StAX 方法。这使用基于游标的 StAX XML 流阅读器(不是替代的 StAX 事件阅读器),因为正如“比较游标和迭代器 API”部分中所说的 here

    如果您正在为内存特别受限的环境(如 Java ME)进行编程,则可以使用游标 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>
    

    【讨论】:

    • 这看起来很棒,我当然可以使用它,但是我可以在我似乎无法在任何地方看到的 Android 上使用 StAX 吗?我似乎被推回了 simplexml。如果您能看到使用 StAX 的方法,我不介意我使用哪个 API,我会这样做吗?非常感谢您帮助您成为上帝派来的人。
    • 我可以在 android 上使用 stax 吗? 我不知道 - 它可能不受支持。也许有一个受支持并以类似方式工作的库。我对 Android 库不了解。
    • PullParser 能做到吗?您认为查看文档吗?找不到图书馆? developer.android.com/reference/org/xmlpull/v1/…
    • 看起来它的工作方式与我的 StAX 示例非常相似。 XmlPullParser xpp = factory.newPullParser(); 然后xpp.getText() 等方法获取标签的内容,比如40.69330963xpp.getAttributeValue(0) 获取第一个属性(你的latlonname...字符串)。很好的发现!
    猜你喜欢
    • 2010-12-27
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2020-03-13
    相关资源
    最近更新 更多