当前位置: 首页 > 面试题库 >

ANDROID:解析XML

苏坚成
2023-03-14
问题内容

我不是开发人员,只是涉足编程。我从来不了解的一个领域是XML解析。可悲的是,对于我最新的“项目”,我需要为一个Android应用执行此操作。它是我正在工作的原型。

我有这个XML(模型文件):

<feed version="201010011221" > 
  <period from="2010-10-01T10:08:34Z" to="2010-10-01T10:08:34Z"> 
    <lines> 
      <line id="SKI" name="Ski" shortname="ski" status="1 calls queued"> 
        <calls> 
          <call id="6584" created="2010-10-01T11:22:42Z">
            <booking>1275243</booking>
          </call> 
        </calls> 
      </line> 
      <line id="CRU" name="Cruise" shortname="cruise" status="0 calls queued"> 
        <calls /> 
      </line> 
      <line id="VIL" name="Villas" shortname="villas" status="2 calls queued"> 
        <calls> 
          <call id="25878" created="2010-10-01T10:22:42Z">
            <booking>1077244</booking>
          </call> 
          <call id="25878" created="2010-10-01T10:22:42Z">
            <booking>1077244</booking>
          </call> 
        </calls> 
      </line>
    </lines>
  </period> 
</feed>

我有一些代码可以让我获得每个的NodeList:

inputStream = OpenHttpConnection(URL);
Document document = null;
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder;
documentBuilder = documentBuilderFactory.newDocumentBuilder();
document = documentBuilder.parse(inputStream);
document.getDocumentElement().normalize();
NodeList lineNodes = document.getElementsByTagName("line");

我不确定下一步该怎么做。我的代码对此似乎很长。我一直在搜寻更好的方法,但发现一些更简洁的代码,无法上班。

有没有很好的Android XML教程?或者有人可以协助我处理此代码?

我需要将每个都放入HashMap中,其中String是ID。

线是显示的所有信息的类别。

谢谢尼尔


问题答案:

我宁可不要使用DOM,因为它具有更大的内存空间。使用DOM,首先将整个XML结构加载到内存中,然后对其进行处理。这可能不是移动开发的最佳解决方案。

使用Android随附的SAX解析器。这是一种事件驱动的方法。每个开始标签,标签之间的内容以及结束标签都会在它们发生时触发事件。实际上,它可以处理更多事件,但那些是最常用的事件。这意味着SAX解析器将逐行处理每一行,而无需先将整个XML结构加载到内存中。

我明天将为您的特定问题提供示例。

编辑:这是承诺的内容处理程序示例。

import java.util.HashMap;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

public class MyContentHandler implements ContentHandler {

    private HashMap<String, Object> feed;
    private HashMap<String, Object> peroidContent;
    private HashMap<String, Object> callContent;
    private HashMap<String, Object> callsMap;
    private HashMap<String, Object> lineContent;
    private HashMap<String, Object> linesMap;

    private String text;
    private String callId;
    private String lineId;

    @Override
    public void startDocument() throws SAXException {
        /* You can perform some action in this method
         * for example to reset some sort of Collection
         * or any other variable you want. It gets called
         * every time a document starts. */
        feed = new HashMap<String, Object>();
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        // Gets called every time an opening tag is encountered.
        if(localName.equalsIgnoreCase("FEED")) {
            /* We've found a "feed" opening tag so we capture its
             * version attribute and put it into our HashMap.*/
            feed.put("Version", atts.getValue("version"));
        } else if(localName.equalsIgnoreCase("PEROID")) {
            peroidContent = new HashMap<String, Object>();
            peroidContent.put("From", atts.getValue("from"));
            peroidContent.put("to", atts.getValue("to"));
        } else if(localName.equalsIgnoreCase("LINE")) {
            linesMap = new HashMap<String, Object>();
        } else if(localName.equalsIgnoreCase("LINE")) {
            lineContent = new HashMap<String, Object>();
            lineId = atts.getValue("id");
            lineContent.put("name", atts.getValue("name"));
            lineContent.put("shortname", atts.getValue("shortname"));
            lineContent.put("status", atts.getValue("status"));
        } else if(localName.equalsIgnoreCase("CALLS")) {
            callsMap = new HashMap<String, Object>();
        } else if(localName.equalsIgnoreCase("CALL")) {
            callContent = new HashMap<String, Object>();
            callId = atts.getValue("Id");
            callContent.put("created", atts.getValue("created"));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        /* Gets called every time in between an opening tag and
         * a closing tag if characters are encountered. */
        text = new String(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // Gets called every time a closing tag is encountered.
        if(localName.equalsIgnoreCase("FEED")) {
            feed.put("Peroid", peroidContent);
        } else if(localName.equalsIgnoreCase("PEROID")) {
            peroidContent.put("Lines", linesMap);
        } else if(localName.equalsIgnoreCase("LINES")) {
            linesMap.put(lineId, lineContent);
        } else if(localName.equalsIgnoreCase("LINE")) {
            lineContent.put("Calls", callsMap);
        } else if(localName.equalsIgnoreCase("CALLS")) {
            callsMap.put(callId, callContent);
        } else if(localName.equalsIgnoreCase("BOOKING")) {
            callContent.put("Booking", text.toString());
        }
    }

    @Override
    public void endDocument() throws SAXException {
        /* You can perform some action in this method
         * for example to reset some sort of Collection
         * or any other variable you want. It gets called
         * every time a document end is reached. */
        SAXParsingFun.setHashMap(feed);
    }

    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void processingInstruction(String target, String data)
            throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        // TODO Auto-generated method stub
    }

    @Override
    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void startPrefixMapping(String prefix, String uri)
            throws SAXException {
        // TODO Auto-generated method stub
    }
}

关于StackOverflow,有很多关于如何解析XML文件的解释,我省略了,只是向您展示了更有趣的部分。内容处理程序。

现在,对大多数有趣的部分都进行了评论,以便您了解我正在尝试做的事情。

我已经实现了该接口,ContentHandler只是为了向您显示有更多可用的方法,也许将来您会需要其中一种。但是,您可以DefaultHandler改为从类扩展而仅覆盖所需的方法。您要做的基本上就是检查某些标签的发生,然后在此之后触发某些事件。如果要保留XML文件中元素的顺序,则只需使用a
LinkedHashMap而不是a HashMap

希望对您有所帮助。



 类似资料:
  • 如果我运行一个普通的JAVA项目,上面的函数可以正常工作,但是如果我在android项目中运行它,它会返回false。问题出在哪里?如何在android项目中预览e.printstacktrace,以便查看异常情况?

  • 问题内容: 我有这样的XML: 现在,我学习Kotlin进行翻新。我包括用于解析xml的库,但我不明白如何创建用于解析此xml的对象。我有对象: 但我有错误: rg.simpleframework.xml.core.ConstructorException:默认构造函数无法接受类ac中方法“ aries”上的@ org.simpleframework.xml.Element(data = fals

  • 问题内容: 我在将json解析到我的android应用中时遇到了一些问题。 这是我的json文件的样子: 如您所见,这种结构有点奇怪。我不知道如何在我的应用程序中读取该数据。我注意到那些都是对象而不是数组:/ 问题答案: 更新2018 5年后,在Android上解析json有了新的“标准”。它被称为moshi,人们可以认为它是GSON 2.0。它非常相似,但已修复了设计错误,这是您开始使用它时遇到

  • 本文向大家介绍android JSON解析数据 android解析天气预报,包括了android JSON解析数据 android解析天气预报的使用技巧和注意事项,需要的朋友参考一下 概要 笔者近期做到对天气预报JSON数据解析,在此小记。 天气预报接口:http://wthrcdn.etouch.cn/weather_mini?citykey=101200101 JSON数据如下: 最终解析效果

  • 我在尝试向手机显示JSON数据时遇到了这个问题 这是我的错误消息 9-29 11:28:24.657 29264-29264/com . example . window 8 . my friend D/Android runtime:正在关闭虚拟机09-29 11:28:24.657 29264-29264/com . example . window 8 . my friend W/dalvi

  • 主要内容:本节引言:,1.XML数据要点介绍,2.三种解析XML方法的比较,3.SAX解析XML数据,4.DOM解析XML数据,5.PULL解析XML数据,6.代码示例下载:,本节小结:本节引言: 前面两节我们对Android内置的Http请求方式:HttpURLConnection和HttpClient,本来以为OkHttp 已经集成进来了,然后想讲解下Okhttp的基本用法,后来发现还是要导第三方,算了,放到进阶部分 吧,而本节我们来学习下Android为我们提供的三种解析XML数据的方案!