AndroidプログラムでXMLファイルを解析する方法と、PULLを使ってXMLケースを解析します.


一、一般的にXMLファイルを解析する方法はSAXとDOM、PULLがあります.
(1)DOM(JAXP Crimson解析器)
DOMは、XMLドキュメントの公式W 3 C規格をプラットフォームや言語に関係なく表しています.DOMは、階層構造で組織されるノードまたは情報の断片の集合である.この階層構造は、開発者が木の中で特定の情報を見つけることを可能にする.この構造を分析するには、一般的にドキュメント全体と階層構造をロードしてから作業ができます.情報レベルに基づいているので、DOMは、ツリーベースまたはオブジェクトベースと考えられる.DOMおよび一般化したツリーベースの処理はいくつかの利点を有する.まず、ツリーはメモリに長いので、アプリケーションがデータと構造を変更できるように修正できます.また、SAXのように使い捨ての処理ではなく、いつでも木の中を上下してナビゲーションすることができます.DOMは使いやすいです.
(2)SAX
SAX処理の利点は流れメディアの利点と非常に似ている.分析はすぐに開始できるが、すべてのデータが処理されるのを待つのではない.また、アプリケーションはデータを読み出す時だけデータをチェックするので、メモリにデータを記憶する必要はありません.これは大きなドキュメントにとって大きな利点です.実際、アプリケーションはドキュメント全体を解析する必要さえありません.ある条件が満たされたら解析を停止することができます.一般的に、SAXはその代替者DOMよりずっと速いです.
  DOM    SAX?              XML         ,   DOM  SAX                。 
DOMは,ツリー構造を確立する方式でXMLドキュメントにアクセスし,SAXが採用するイベントモデルを採用した.
DOM    XML              ,         。 DOM            ,              ,     
navigation
APIは、タスクを完了するために必要なツリーノードにアクセスする.ツリーの要素を簡単に追加して修正できます.しかし、DOM解析器を使用する場合はXMLファイル全体を処理する必要があるため、性能やメモリに対する要求が高く、特に大きなXMLファイルに遭遇した場合.そのエルゴード能力のため、DOM解析器はXMLドキュメントに頻繁に変更する必要があるサービスによく使われています.
SAX解析器はイベントベースのモデルを採用しており、XMLドキュメントを解析する際に一連のイベントをトリガすることができ、所与のタグが発見された時に、この方法で作成されたラベルが見つかったことを教えてくれます.SAXのメモリに対する要求は一般的に低くなります.それは開発者自身に処理すべきものを決定させます.特に開発者が文書に含まれているデータの一部だけを処理する必要がある場合、SAXのこのような拡張能力はより良い表現を得ました.しかし、SAX解析器を使う時はエンコードが難しいし、同じ文書の多くの異なるデータに同時にアクセスするのは難しいです.
(3)JDOM
JDOMの目的はJava特定のドキュメントモデルになることであり、XMLとの相互作用を簡略化し、DOMを使用するより早く実現することである.最初のJava特定モデルであるため、JDOMは強力なプロモーションと促進を受けてきた.「Java仕様要求JSR-102」によって最終的に「Java標準拡張」として使用することが考えられています.2000年の初めからすでにJDOM開発が始まりました.
JDOMとDOMは主に2つの点で異なる.まず、JDOMはインターフェースを使用せずに具体的なクラスだけを使用します.これはいくつかの態様では、APIが簡略化されているが、柔軟性も制限されている.第二に、APIはCollectionクラスを大量に使用しており、これらの種類に精通しているJava開発者の使用を簡略化している.
JDOM        “  20%(   )     80%(   )Java/XML  ”(         20%)。JDOM      
Java/XMLアプリケーションはもちろん有用であり、多くの開発者は、APIがDOMよりもはるかに理解しやすいことを発見している.JDOMはまた、XMLにおいてユーザが無意味なことをすることを防止するために、プログラム行動のかなり広い検査を含む.しかし、XMLを十分に理解して、基本を超えた仕事をする必要があります.これはDOMやJDOMインターフェースを学ぶよりも有意義な仕事かもしれません.
JDOM自体には解析器は含まれていません.これは通常、SAX 2解像器を使用して入力XMLドキュメントを解析し、検証しています.これはいくつかの変換器を含み、JDOM表現をSAX 2イベントフロー、DOMモデルまたはXML文書ドキュメントに出力します.JDOMはApacheライセンスの下でリリースされたオープンソースです.
(4)DOM 4 J
  DOM4J            ,   ,  JDOM       。          XML       ,     XPath  、 
XML Schemaサポートおよび大ドキュメントまたはストリーミングドキュメントのイベントベースの処理.また、DOM 4 J APIと標準DOMインターフェースを介して、ドキュメント表現を構築するオプションも提供されています.2000年後半からずっと開発中です.
これらのすべての機能をサポートするために、DOM 4 Jはインターフェースと抽象基本クラスの方法を使用します.DOM 4 JはAPIにおけるCollectionクラスを多く使用しているが、多くの場合、より良い性能またはより直接的な符号化方法を可能にする代替方法を提供している.直接の利点は、DOM 4 Jはより複雑なAPIの代償を払っているが、JDOMよりもはるかに大きな柔軟性を提供している.
      、XPath             ,DOM4J    JDOM    :  Java            。         
JDOMのより完全な解決策は、本質的にすべてのJava/XML問題を処理する目標を実現する.この目標を達成する時、JDOMよりも少ないです.不正なアプリケーション行為を防止することを強調します.
DOM4J          Java XML 
APIは、性能が優れ、機能が強く、使いやすいという特徴を持っています.同時に、オープンソースコードのソフトウェアです.今はますます多くのJavaソフトウェアがDOM 4 Jを使ってXMLを読み、書くことができます.特に言及すべきはSunのJAXMもDOM 4 Jを使っています.
(5)比較
1)DOM 4 Jは最高性能で、SunのJAXMもDOM 4 Jを使用しています.現在多くのオープンソース項目では、DOM 4 Jを大量に採用しています.例えば、有名なHbernateもDOM 4 JでXMLプロファイルを読み込みます.移植可能性を考慮しないなら、DOM 4 Jを採用します.
2)JDOMとDOMは性能テスト時にパフォーマンスが良くなく、10 Mドキュメントをテストする時にメモリが溢れます.小さい文書の場合はDOMとJDOMを使うことを考慮する価値があります.JDOMの開発者は正式版の前で性能の問題に専念することを期待していると説明しましたが、性能の観点から見ると、確かにオススメするところがありません.また、DOMは非常に良い選択です.DOM実現は多くのプログラミング言語に広く応用されている.これはまだ多くの他のXMLに関する標準的な基礎であり、W 3 Cの推奨を正式に獲得しているため(標準ではないJavaモデルに対して)、いくつかのタイプのプロジェクトにもそれが必要である可能性がある(JavaScriptでDOMを使用する場合など).
3)SAXの表現が良く、これはその特定の解析方式-イベント駆動に依存する.SAXは、XMLフローを検出しましたが、メモリにロードされていません.もちろんXMLストリームが読み込まれた時、一部のドキュメントは一時的にメモリに隠しています.
(6)4種類のXML操作方式の基本的な使い方
xml  :
 <?xml version="1.0" encoding="GB2312"?>

    <RESULT>

    <VALUE>

    <NO>A1234</NO>

    <ADDR>   XX XX XX X XX </ADDR>

    </VALUE>

    <VALUE>

    <NO>B1234</NO>

    <ADDR>   XX XX XX XX </ADDR>

    </VALUE>    </RESULT>  
1)DOM
import java.io.*;

    import java.util.*;

    import org.w3c.dom.*;

    import javax.xml.parsers.*;

    public class MyXMLReader{

    public static void main(String arge[]){

    long lasting =System.currentTimeMillis();

    try{

    File f=new File("data_10k.xml");

    DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();

    DocumentBuilder builder=factory.newDocumentBuilder();

    Document doc = builder.parse(f);

    NodeList nl = doc.getElementsByTagName("VALUE");

    for (int i=0;i<nl.getLength();i++){

    System.out.print("    :" +


doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());

    System.out.println("    :" +


doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());

    }

    }catch(Exception e){

    e.printStackTrace();

    }
2)SAX
 import org.xml.sax.*;

    import org.xml.sax.helpers.*;

    import javax.xml.parsers.*;

    public class MyXMLReader extends DefaultHandler {

    java.util.Stack tags = new java.util.Stack();

    public MyXMLReader() {

    super();

    }

    public static void main(String args[]) {

    long lasting = System.currentTimeMillis();

    try {

    SAXParserFactory sf = SAXParserFactory.newInstance();

    SAXParser sp = sf.newSAXParser();

    MyXMLReader reader = new MyXMLReader();

    sp.parse(new InputSource("data_10k.xml"), reader);

    } catch (Exception e) {

    e.printStackTrace();

    }

    System.out.println("    :" + (System.currentTimeMillis() - lasting) + 
"  ");}

    public void characters(char ch[], int start, int length) throws 
SAXException {

    String tag = (String) tags.peek();

    if (tag.equals("NO")) {

    System.out.print("    :" + new String(ch, start, length));

    }

    if (tag.equals("ADDR")) {

    System.out.println("  :" + new String(ch, start, length));

    }

    }

    public void startElement(String uri,String localName,String 
qName,Attributes attrs) {

    tags.push(qName);}    }
3)JDOM
 import java.io.*;

    import java.util.*;

    import org.jdom.*;

    import org.jdom.input.*;

    public class MyXMLReader {

    public static void main(String arge[]) {

    long lasting = System.currentTimeMillis();

    try {

    SAXBuilder builder = new SAXBuilder();

    Document doc = builder.build(new File("data_10k.xml"));

    Element foo = doc.getRootElement();

    List allChildren = foo.getChildren();

    for(int i=0;i<allChildren.size();i++) {

    System.out.print("    :" +

    ((Element)allChildren.get(i)).getChild("NO").getText());

    System.out.println("    :" +

    ((Element)allChildren.get(i)).getChild("ADDR").getText());

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }
4)DOM4J
 import java.io.*;

    import java.util.*;

    import org.dom4j.*;

    import org.dom4j.io.*;

    public class MyXMLReader {

    public static void main(String arge[]) {

    long lasting = System.currentTimeMillis();

    try {

    File f = new File("data_10k.xml");

    SAXReader reader = new SAXReader();

    Document doc = reader.read(f);

    Element root = doc.getRootElement();

    Element foo;

    for (Iterator i = root.elementIterator("VALUE"); i.hasNext() {

    foo = (Element) i.next();

    System.out.print("    :" + foo.elementText("NO"));

    System.out.println("    :" + foo.elementText("ADDR"));

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    )
二、PULLを使ってXMLを解析して保存するケース
GoogleはAndoidにPULLを統合したAPIが相対的に多いため、PULLの性能がいいです.PULLを使う方法を紹介します.
person.xmlファイルは以下の通りです.
<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="23">
        <name>liming</name>
        <age>30</age>
    </person>
    <person id="20">
        <name>zhangxiaoxiao</name>
        <age>25</age>
    </person>
</persons>
Person.javaはxmlファイルに対応するデータを表しています.
package cn.xuliugen.domain;

public class Person {
    private Integer id;
    private String name;
    private Integer age;
    //get、set    
}
PersonService.javaは主に解析xmlファイルとxmlファイルにデータを保存するための2つの方法です.
package cn.xuliugen.service;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;

import cn.xuliugen.domain.Person;

public class PersonService {
    /** *      :Android     PULL    * @param xml * @return * @throws Exception */
    public static List<Person> getPersons(InputStream xml) throws Exception{
        List<Person> persons = null;
        Person person = null;
        XmlPullParser pullParser = Xml.newPullParser();
        pullParser.setInput(xml, "UTF-8");// Pull         XML  
        int event = pullParser.getEventType(); //    
        while(event != XmlPullParser.END_DOCUMENT){ //           :    
            switch (event) {
            case XmlPullParser.START_DOCUMENT: //     :xml  
                persons = new ArrayList<Person>();
                break;

            case XmlPullParser.START_TAG:
                if("person".equals(pullParser.getName())){ //        person
                    int id = new Integer(pullParser.getAttributeValue(0));
                    person = new Person();
                    person.setId(id);
                }
                if("name".equals(pullParser.getName())){
                    String name = pullParser.nextText();//          
                    person.setName(name);
                }
                if("age".equals(pullParser.getName())){
                    int age = new Integer(pullParser.nextText());
                    person.setAge(age);
                }
                break;

            case XmlPullParser.END_TAG: //     
                if("person".equals(pullParser.getName())){
                    persons.add(person); // person   list 
                    person = null;
                }
                break;
            }  
            event = pullParser.next(); //pull           ,    next
        }
        return persons;
    }
    /** *      * @param persons    * @param out      * @throws Exception */
    public static void save(List<Person> persons, OutputStream out) throws Exception{
        XmlSerializer serializer = Xml.newSerializer(); //XML    
        serializer.setOutput(out, "UTF-8"); //         
        serializer.startDocument("UTF-8", true); //    xml        :true          
        serializer.startTag(null, "persons"); //       :null         
        for(Person person : persons){
            serializer.startTag(null, "person");
            serializer.attribute(null, "id", person.getId().toString());

            serializer.startTag(null, "name");
            serializer.text(person.getName());
            serializer.endTag(null, "name");

            serializer.startTag(null, "age");
            serializer.text(person.getAge().toString());
            serializer.endTag(null, "age");

            serializer.endTag(null, "person");
        }
        serializer.endTag(null, "persons"); //       
        serializer.endDocument();

        out.flush();
        out.close();
    }
}
PersonServiceTest.javaは効果をテストするために使用します.ここではリストファイルにユニットテストの権限を入れます.
package cn.xuliugen.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import cn.xuliugen.domain.Person;
import cn.xuliugen.service.PersonService;
import android.test.AndroidTestCase;
import android.util.Log;

public class PersonServiceTest extends AndroidTestCase {
    private static final String TAG = "PersonServiceTest";

    public void testPersons() throws Exception{
        InputStream xml = this.getClass().getClassLoader().getResourceAsStream("person.xml");
        List<Person> persons = PersonService.getPersons(xml);
        for(Person person : persons){
            Log.i(TAG, person.toString()); //      Person     toString  
        }
    }

    public void testSave() throws Exception{
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person(43, "zhangxx", 80));
        persons.add(new Person(12, "lili", 20));
        persons.add(new Person(78, "xiaoxiao", 8));
        // < >/files
        File xmlFile = new File(getContext().getFilesDir(), "itcast.xml");
        FileOutputStream outStream = new FileOutputStream(xmlFile);
        PersonService.save(persons, outStream);
    }
}
MainActivity.javaとレイアウトファイルは何も変更されていません.効果は以下の通りです