Heim  >  Artikel  >  Backend-Entwicklung  >  Zusammenfassung der XML-Dateianalyse. Detaillierte Einführung in SAX/DOM/PULL

Zusammenfassung der XML-Dateianalyse. Detaillierte Einführung in SAX/DOM/PULL

黄舟
黄舟Original
2017-03-18 17:37:251666Durchsuche

Wenn Sie beim Lesen Fragen oder Fehler haben, hinterlassen Sie bitte Kommentare oder fügen Sie mich unter Penguin 1262135886 hinzu. Vielen Dank, dass Sie den Unterschied zwischen SAX, DOM4J und PULL-Parsing unterstützen

Sax-Funktionen (SAX ist einfach API für Die Abkürzung von XML)

Hohe Parsing-Effizienz und geringer Speicherverbrauch

2 jederzeit

3. Das gesamte Dokument kann nicht in den Speicher geladen werden

4. XML kann nicht geschrieben werden

5 🎜>TreiberDer Unterschied zwischen Pull und Sax

1 Nachdem Pull die XML-Datei gelesen hat, löst er das entsprechende Ereignis aus und ruft die Methode auf, um eine Zahl zurückzugeben.

2. Pull kann im Programm gesteuert werden, und Sie können anhalten, wo immer Sie möchten

3

Android

wird eher empfohlen, Pull-Parsing zu verwenden

Funktionen von DOM

Vorteile

1. Der gesamte

Dokumentenbaum

ist im Speicher, einfach zu bedienen; unterstützt

Löschen, Neu anordnen usw. Funktionen2. Zugriff auf XML-Dokumente über die Baumstruktur

3. Sie können sich auf einem Knoten im Baum vorwärts oder rückwärts bewegen

Nachteile

1. Übertragen Sie das gesamte Dokument in den Speicher (einschließlich nutzloser Knoten), was Zeit und Platz verschwendet

Anwendbare Anlässe

Sobald das Dokument analysiert ist, muss mehrmals auf die Daten zugegriffen werden. Hardwareressourcen Ausreichend (Speicher, CPU)

Zuerst definieren Ich habe eine Student.xml-Datei definiert

**Beispiel**


**1. sax Parsing**

[code]<?xml version="1.0" encoding="utf-8"?>
<students>

    <student id="1" >

        <name>
小红
        </name>

        <age>
21
        </age>

        <sex>
女
        </sex>

        <adress>
上海
        </adress>
    </student>

    <student id="2" >

        <name>
小黑
        </name>

        <age>
22
        </age>

        <sex>
男
        </sex>

        <adress>
天津
        </adress>
    </student>

    <student id="3" >

        <name>
小网
        </name>

        <age>
23
        </age>

        <sex>
男
        </sex>

        <adress>
北京
        </adress>
    </student>

</students>


**Selbstdefinierte ContentHandler-Klasse**

[code]package com.example.sax_xml;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sax_xml(View v) {
        // 得到设备管理者对象
        AssetManager manager = this.getAssets();
        try {
            // 获取到assets目录下的Student.xml文件输入流
            InputStream is = manager.open("Student.xml");
            /**
             * SAXParserFactory 定义了一个API工厂,使得应用程序可以配置和获得一个基于SAX(Simple API for
             * XML
             * 
             * )的解析器,从而能够解析XML文档( 原文: Defines a factory API that enables
             * applications to configure and obtain a SAX based parser to parse
             * XML documents. )
             * 
             * 它的构造器是受保护的,因而只能用newInstance()方法获得实例( Protected constructor to
             * force use of newInstance(). )
             */
            SAXParserFactory factory = SAXParserFactory.newInstance();

            /**
             * XmlReader 类是一个提供对 XML 数据的非缓存、只进只读访问的抽象基类。 该类符合 W3C 可扩展标记语言 (XML)
             * 1.0 和 XML 中的命名空间的建议。 XmlReader 类支持从流或文件读取 XML 数据。
             * 该类定义的方法和属性使您可以浏览数据并读取节点的内容。 当前节点指读取器所处的节点。
             * 使用任何返回当前节点值的读取方法和属性推进读取器。 XmlReader 类使您可以: 1. 检查字符是不是合法的
             * XML字符,元素和属性的名称是不是有效的 XML 名称。 2. 检查 XML 文档的格式是否正确。 3. 根据 DTD
             * 或架构验证数据。 4.从 XML流检索数据或使用提取模型跳过不需要的记录。
             */
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            /**
             * ContentHandler是Java类包中一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法
             * ,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束、元素开头和结束、以及元素中的字符数据等事件
             * 。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。
             */
            //由于它是一个接口所以我直接编写一个类继承它的子类DefaultHandler,重新其方法
            ContentHandler handler = new ContentHandler();
            // 将ContentHandler的实例设置到XMLReader中
            // setContentHandler此方法设置 XML 读取器的内容处理程序
            xmlReader.setContentHandler(handler);
            // 开始执行解析
            //InputSource:XML 实体的单一输入源。
            xmlReader.parse(new InputSource(is));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

**2.Pull-Parsing**

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class ContentHandler extends DefaultHandler {

    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder sex;
    private StringBuilder age;
    private StringBuilder adress;
    private String nodeName;// 记录当前节点的名字

    // 开始xml解析的时候调用
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        sex = new StringBuilder();
        age = new StringBuilder();
        adress = new StringBuilder();
    }

    // 开始解析某个节点的时候调用
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        nodeName = localName;
    }

    // 获取某个节点中的内容时调用
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if ("id".equals(nodeName)) {
            id.append(ch, start, length);
        } else if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("age".equals(nodeName)) {
            age.append(ch, start, length);
        } else if ("sex".equals(nodeName)) {
            sex.append(ch, start, length);
        } else if ("adress".equals(nodeName)) {
            adress.append(ch, start, length);
        }
    }

    //完成某个节点的解析的时候调用
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if ("student".equals(localName)) {
            Log.d("ContentHandler", "id is" + id.toString().trim());
            Log.d("ContentHandler", "name is" + name.toString().trim());
            Log.d("ContentHandler", "age is" + age.toString().trim());
            Log.d("ContentHandler", "sex is" + sex.toString().trim());
            Log.d("ContentHandler", "adress is" + adress.toString().trim());
            // 最后要将StringBuilder清空掉
            id.setLength(0);
            name.setLength(0);
            age.setLength(0);
            sex.setLength(0);
            adress.setLength(0);
        }
    }

    //完成整个XML解析的时候调用
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
    }
}


Lassen Sie uns zunächst darüber sprechen, worauf Sie beim DOM-Parsen achten müssen, da unser Lehrer diesen Fehler gemacht hat, als er darüber sprach, möchte ich hier darauf hinweisen

[code]package com.example.xmlpull;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.widget.Toast;

import org.xmlpull.v1.XmlPullParser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 *         读取到xml的声明返回数字0 START_DOCUMENT; 
 *         读取到xml的结束返回数字1 END_DOCUMENT ;
 *         读取到xml的开始标签返回数字2 START_TAG 
 *         读取到xml的结束标签返回数字3 END_TAG 
 *         读取到xml的文本返回数字4  TEXT
 * 
 */
public class MainActivity extends Activity {
    /**
     * 用于装载解析出来的数据
     */
    private List<Map<String, Object>> oList;
    private Map<String, Object> oMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    public void btn_pull(View v) {
        // 获取设备管理器对象
        AssetManager manager = this.getAssets();
        try {
            // 得到assets文件下的Student.xml文件输入流
            InputStream is = manager.open("Student.xml");
            // 得到pull解析对象,它的构造器是受保护的,因而只能用newInstance()方法获得实例
            XmlPullParser parser = Xml.newPullParser();
            // 将xml文件输入流传给pull解析对象
            parser.setInput(is, "UTF-8");
            // 获取解析时的事件类型,
            int type = parser.getEventType();
            // 使用while循环,如果解析的事件类型不等于全文档最后节点类型,一直解析
            while (type != XmlPullParser.END_DOCUMENT) {
                // 得到当前的节点名字
                String nodeName = parser.getName();
                switch (type) {
                // 如果是全文档的开始节点类型
                case XmlPullParser.START_DOCUMENT:
                    // 初始化装载数据的集合
                    oList = new ArrayList<Map<String, Object>>();
                    break;

                // 如果是group开始节点类型
                case XmlPullParser.START_TAG:
                    // 根据解析的节点名字进行判断
                    if ("students".equals(nodeName)) {

                    } else if ("student".equals(nodeName)) {
                        oMap = new HashMap<String, Object>();
                        // 得到group开头的student节点
                        String id = parser.getAttributeValue(0);
                        oMap.put("id", id);
                    } else if ("name".equals(nodeName)) {
                        // 节点对应的文本
                        String name = parser.nextText();
                        oMap.put("name", name);
                    } else if ("sex".equals(nodeName)) {
                        String sex = parser.nextText();
                        oMap.put("sex", sex);
                    } else if ("age".equals(nodeName)) {
                        String age = parser.nextText();
                        oMap.put("age", age);
                    } else if ("adress".equals(nodeName)) {
                        String adress = parser.nextText();
                        oMap.put("adress", adress);
                    }
                    break;

                // 到了group最后的节点
                case XmlPullParser.END_TAG:
                    if ("name".equals(nodeName)) {
                        Toast.makeText(this, "姓名解析完成", Toast.LENGTH_LONG)
                                .show();
                    }
                    if ("student".equals(nodeName)) {
                        oList.add(oMap);
                    }
                    break;
                }

                //切换到下一个group
                type = parser.next();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //最后遍历集合Log
        for (int i = 0; i < oList.size(); i++) {

            Log.e("error",
                    "name:" + oList.get(i).get("name") + "----sex:"
                            + oList.get(i).get("sex") + "----age:"
                            + oList.get(i).get("age") + "----address:"
                            + oList.get(i).get("adress"));
        }

    }

}

Wenn wir hier erhalten: Wenn der Knoten Student ist, wo der Pfeil im Bild gezeichnet ist, rufen wir seine getChildNodes()-Methode auf. Ratet mal, wie viele untergeordnete Knoten er hat? Seine Enkelknoten sind nicht enthalten, mit Ausnahme von Xiaohong, da es sich um einen Enkelknoten handelt. Es verfügt über insgesamt 5 untergeordnete Knoten, die in der Abbildung durch die schwarzen horizontalen Linien gekennzeichnet sind. Achten Sie daher beim Parsen darauf, Leerzeichen nicht zu ignorieren. Zusammenfassung der XML-Dateianalyse. Detaillierte Einführung in SAX/DOM/PULL

Der spezifische Parsing-Code ist unten angehängt

Hier teile ich den DOM-Parsing-Teil in eine Tool-Klasse auf

Student.class
[code]package com.example.domxml;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *Dom解析是将xml文件全部载入,组装成一颗dom树,
 *然后通过节点以及节点之间的关系来解析xml文件,一层一层拨开
 */
public class Dom_xml_Util {
    private List<Student> list = new ArrayList<Student>();  
    public List<Student> getStudents(InputStream in) throws Exception{
        //获取dom解析工厂,它的构造器是受保护的,因而只能用newInstance()方法获得实例
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //使用当前配置的参数创建一个新的 DocumentBuilder 实例
        //DocumentBuilder使其从 XML 文档获取 DOM 文档实例。
        //使用此类,应用程序员可以从 XML 获取一个 Document
        DocumentBuilder builder = factory.newDocumentBuilder();  
        //获取Document
        Document document = builder.parse(in); 
        //getDocumentElement()这是一种便捷属性,该属性允许直接访问文档的文档元素的子节点
        //Element 接口表示 HTML 或 XML 文档中的一个元素
        Element element = document.getDocumentElement();  
        //以文档顺序返回具有给定标记名称的所有后代 Elements 的 NodeList
        NodeList bookNodes = element.getElementsByTagName("student"); 
        //遍历NodeList
        //getLength()列表中的节点数
        for(int i=0;i<bookNodes.getLength();i++){  
            //返回集合中的第 i个项
            Element bookElement = (Element) bookNodes.item(i);  
            Student student = new Student();  
            //得到item大节点中的属性值。
            student.setId(Integer.parseInt(bookElement.getAttribute("id"))); 
            //得到大节点中的小节点的Nodelist
            NodeList childNodes = bookElement.getChildNodes();  
//          System.out.println("*****"+childNodes.getLength());  
            //遍历小节点
            for(int j=0;j<childNodes.getLength();j++){  
                /**
                 * getNodeType()表示基础对象的类型的节点
                 * Node.ELEMENT_NODE  该节点为 Element
                 * getNodeName()此节点的名称,取决于其类型
                 * getFirstChild() 此节点的第一个子节点
                 * getNodeValue()此节点的值,取决于其类型
                 */
                if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE){  
                    if("name".equals(childNodes.item(j).getNodeName())){  
                        student.setName(childNodes.item(j).getFirstChild().getNodeValue());  
                    }else if("age".equals(childNodes.item(j).getNodeName())){  
                        student.setAge(Integer.parseInt(childNodes.item(j).getFirstChild().getNodeValue()));  
                    }else if("sex".equals(childNodes.item(j).getNodeName())){  
                        student.setSex(childNodes.item(j).getFirstChild().getNodeValue());  
                    }else if("address".equals(childNodes.item(j).getNodeName())){  
                        student.setAddress(childNodes.item(j).getFirstChild().getNodeValue());  
                    }  
                }  
            }//end for j  
            list.add(student);  
        }//end for i  
        return list;
    }
}

Aufruf

[code]package com.example.domxml;

public class Student {

    private int id;
    private String name;
    private int age;
    private String sex;
    private String address;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}
activity_main

MainActivity

[code]<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
     <TextView
        android:id="@+id/tv_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
      <TextView
        android:id="@+id/tv_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
       <TextView
        android:id="@+id/tv_sex"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
        <TextView
        android:id="@+id/tv_adress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

[code]package com.example.domxml;

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

import android.os.Bundle;
import android.app.Activity;
import android.content.res.AssetManager;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView tv_id,tv_name,tv_age,tv_sex,tv_adress;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_id=(TextView)findViewById(R.id.tv_id);
        tv_name=(TextView)findViewById(R.id.tv_name);
        tv_age=(TextView)findViewById(R.id.tv_age);
        tv_sex=(TextView)findViewById(R.id.tv_sex);
        tv_adress=(TextView)findViewById(R.id.tv_adress);
    }
    public void bnt_parse(View v) 
    {
        AssetManager manager=getAssets();
        try {
            InputStream in=manager.open("Student.xml");
            List<Student> oList =new ArrayList<Student>();
            try {
                //返回一个泛型为Student的集合
                oList = new Dom_xml_Util().getStudents(in);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //遍历集合,取集合中的第一组数据
            for (int i = 0; i < oList.size(); i++) {
                tv_id.setText(oList.get(0).getId());
                tv_name.setText(oList.get(0).getName());
                tv_age.setText(oList.get(0).getAge());
                tv_sex.setText(oList.get(0).getSex());
                tv_adress.setText(oList.get(0).getAddress());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}


Das obige ist der detaillierte Inhalt vonZusammenfassung der XML-Dateianalyse. Detaillierte Einführung in SAX/DOM/PULL. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn