Android XMLデータの解析


このセクションの概要:

前の 2 つのセクションでは、Android の組み込み Http リクエスト メソッドである HttpURLConnection と HttpClient について説明しました。 統合されました。Okhttp の基本的な使い方を説明しようと思ったのですが、後でサードパーティを導入する必要があることがわかったので、忘れて高度な部分に置きます。 さて、このセクションでは、Android が提供する XML データを解析するための 3 つのソリューションについて学びます。彼らです: 解析方法には SAX、DOM、PULL の 3 つがあります。以下でそれらについて学びましょう。


1. XML データの重要なポイントの紹介

まず、XML データの要件と概念をいくつか見てみましょう:

1.png


2. 3 つの XML 解析方法の比較

2.png


3. XML データを解析する SAX

3.png

コアコード:

SAX 解析クラス:SaxHelper.java:

/**
 * Created by Jay on 2015/9/8 0008.
 */
public class SaxHelper extends DefaultHandler {
    private Person person;
    private ArrayList persons;
    //当前解析的元素标签
    private String tagName = null;

    /**
     * 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
     */
    @Override
    public void startDocument() throws SAXException {
        this.persons = new ArrayList();
        Log.i("SAX", "读取到文档头,开始解析xml");
    }


    /**
     * 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        if (localName.equals("person")) {
            person = new Person();
            person.setId(Integer.parseInt(attributes.getValue("id")));
            Log.i("SAX", "开始处理person元素~");
        }
        this.tagName = localName;
    }


    /**
     * 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
     */

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //判断当前标签是否有效
        if (this.tagName != null) {
            String data = new String(ch, start, length);
            //读取标签中的内容
            if (this.tagName.equals("name")) {
                this.person.setName(data);
                Log.i("SAX", "处理name元素内容");
            } else if (this.tagName.equals("age")) {
                this.person.setAge(Integer.parseInt(data));
                Log.i("SAX", "处理age元素内容");
            }

        }

    }

    /**
     * 处理元素结束时触发,这里将对象添加到结合中
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (localName.equals("person")) {
            this.persons.add(person);
            person = null;
            Log.i("SAX", "处理person元素结束~");
        }
        this.tagName = null;
    }

    /**
     * 读取到文档结尾时触发,
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        Log.i("SAX", "读取到文档尾,xml解析结束");
    }

    //获取persons集合
    public ArrayList getPersons() {
        return persons;
    }

}

そして、MainActivity.java にそのようなメソッドを記述し、XML を解析するときに呼び出します。 大丈夫です~

private ArrayList readxmlForSAX() throws Exception {
    //获取文件资源建立输入流对象
    InputStream is = getAssets().open("person1.xml");
    //①创建XML解析处理器
    SaxHelper ss = new SaxHelper();
    //②得到SAX解析工厂
    SAXParserFactory factory = SAXParserFactory.newInstance();
    //③创建SAX解析器
    SAXParser parser = factory.newSAXParser();
    //④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
    parser.parse(is, ss);
    is.close();
    return ss.getPersons();
}

その他の言葉:

さて、ところで、次のような person1.xml ファイルを定義して、assets ディレクトリに配置したことを言い忘れていました。 ファイルの内容は次のとおりです。 person1.xml

            SAX解析        18                XML1        43

3 つの分析メソッドを 1 つのデモに結合しているため、最後にすべてのレンダリングのみを掲載します。ここでは、印刷されたログを掲載します。 誰もが SAX XML 解析プロセスをより明確に理解できると思います。

4.png

さらに、外側の空白テキストもテキスト ノードです。これらのノードは分析中にもウォークされます。


4.XMLデータを解析するDOM

5.png

コアコード:

DomHelper.java

/**
 * Created by Jay on 2015/9/8 0008.
 */
public class DomHelper {
    public static ArrayList queryXML(Context context)
    {
        ArrayList Persons = new ArrayList();
        try {
            //①获得DOM解析器的工厂示例:
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            //②从Dom工厂中获得dom解析器
            DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
            //③把要解析的xml文件读入Dom解析器
            Document doc = dbBuilder.parse(context.getAssets().open("person2.xml"));
            System.out.println("处理该文档的DomImplemention对象=" + doc.getImplementation());
            //④得到文档中名称为person的元素的结点列表
            NodeList nList = doc.getElementsByTagName("person");
            //⑤遍历该集合,显示集合中的元素以及子元素的名字
            for(int i = 0;i < nList.getLength();i++)
            {
                //先从Person元素开始解析
                Element personElement = (Element) nList.item(i);
                Person p = new Person();
                p.setId(Integer.valueOf(personElement.getAttribute("id")));

                //获取person下的name和age的Note集合
                NodeList childNoList = personElement.getChildNodes();
                for(int j = 0;j < childNoList.getLength();j++)
                {
                    Node childNode = childNoList.item(j);
                    //判断子note类型是否为元素Note
                    if(childNode.getNodeType() == Node.ELEMENT_NODE)
                    {
                        Element childElement = (Element) childNode;
                        if("name".equals(childElement.getNodeName()))
                            p.setName(childElement.getFirstChild().getNodeValue());
                        else if("age".equals(childElement.getNodeName()))
                            p.setAge(Integer.valueOf(childElement.getFirstChild().getNodeValue()));
                    }
                }
                Persons.add(p);
            }
        } catch (Exception e) {e.printStackTrace();}
        return Persons;
    }
}

コード分析:

コードからDOM解析のプロセスがわかりますXML、まず、ファイル全体が Dom パーサーに読み込まれ、ツリーが形成されます。 次に、ノード リストを走査して、必要なデータを取得します。


5.PULL による XML データの解析

6.png

PULL を使用して XML データを解析するプロセス:

7.png

コア コード :

public static ArrayList getPersons(InputStream xml)throws Exception
{
    //XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance();
    ArrayList persons = null;
    Person person = null;
    // 创建一个xml解析的工厂  
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
    // 获得xml解析类的引用  
    XmlPullParser parser = factory.newPullParser();  
    parser.setInput(xml, "UTF-8");  
    // 获得事件的类型  
    int eventType = parser.getEventType();  
    while (eventType != XmlPullParser.END_DOCUMENT) {  
        switch (eventType) {  
        case XmlPullParser.START_DOCUMENT:  
            persons = new ArrayList();  
            break;  
        case XmlPullParser.START_TAG:  
            if ("person".equals(parser.getName())) {  
                person = new Person();  
                // 取出属性值  
                int id = Integer.parseInt(parser.getAttributeValue(0));  
                person.setId(id);  
            } else if ("name".equals(parser.getName())) {  
                String name = parser.nextText();// 获取该节点的内容  
                person.setName(name);  
            } else if ("age".equals(parser.getName())) {  
                int age = Integer.parseInt(parser.nextText());  
                person.setAge(age);  
            }  
            break;  
        case XmlPullParser.END_TAG:  
            if ("person".equals(parser.getName())) {  
                persons.add(person);  
                person = null;  
            }  
            break;  
        }  
        eventType = parser.next();  
    }  
    return persons;  
}

Pull を使用して XML データを生成するプロセス:

8.png

コアコード:

public static void save(List persons, OutputStream out) throws Exception {
    XmlSerializer serializer = Xml.newSerializer();
    serializer.setOutput(out, "UTF-8");
    serializer.startDocument("UTF-8", true);
    serializer.startTag(null, "persons");
    for (Person p : persons) {
        serializer.startTag(null, "person");
        serializer.attribute(null, "id", p.getId() + "");
        serializer.startTag(null, "name");
        serializer.text(p.getName());
        serializer.endTag(null, "name");
        serializer.startTag(null, "age");
        serializer.text(p.getAge() + "");
        serializer.endTag(null, "age");
        serializer.endTag(null, "person");
    }

    serializer.endTag(null, "persons");
    serializer.endDocument();
    out.flush();
    out.close();
}

6. コードサンプルのダウンロード:

レンダリングの実行:

9.gif9.png10.png

コードのダウンロード: XMLParseDemo.zip: ダウンロード XMLParseDe mo.zip


このセクションの概要:

このセクションでは、Android で一般的に使用される 3 つの XML 解析方法、DOM、SAX、および PULL を紹介します。モバイル端末には後者を使用することをお勧めします。 2 つのタイプがあり、PULL の方が使いやすいので、ここでは詳しく説明しません。このセクションはこれで終わりです。 Android が提供する JSON 解析方法を学びましょう。ありがとう〜