DOM操作

       使用文件保存数据时,往往会采用XML文件形式进行数据的保存,一旦使用了XML操作,就需要对XML文件进行解析,今天先来解释下常用的一种解析:DOM解析。

 一、DOM解析是将XML文件全部载入,组装成一颗DOM树,然后通过节点以及节点之间的关系来解析XML文件。

1:要读入一个XML文档,首先要有一个DocumentBuilder对象:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();


2:现在可以从文件中去读取一个XML文件了

    得到XML文件有三种方式:

1:通过文件方式读取:

File file=new File("F:""menber.xml");
Document doc=builder.parse(file);

2:通过一个URL方式读取:

 URL u=new URL("http://java.sun.com/index.html")
Document doc=builder.parse(u);


3:可以能过java IO 流的读取:

 

FileInputStream is = new FileInputStream(  "F:""member.xml");
 Document doc=builder.parse(is);

二、通过程序输出XML文件

首先是我们的布局文件

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20px"
            android:text="姓名:"/>
        <EditText
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </TableRow>
    <TableRow>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20px"
            android:text="邮箱:"/>
        <EditText
            android:id="@+id/email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </TableRow>
    <TableRow>
        <Button
            android:id="@+id/but"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="保存"/>
    </TableRow>
</TableLayout>
<span style="font-size:18px;">用户可以在界面输入姓名和邮箱:</span>


接下来我们来看看java程序,在改程序中,我队一些类和方法进行了注释

package com.administrator.dom;

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

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

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class MainActivity extends AppCompatActivity {
    private TextView name;
    private TextView email;
    private Button save;

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

        name= (TextView) findViewById(R.id.name);
        email= (TextView) findViewById(R.id.email);
        save= (Button) findViewById(R.id.but);

        save.setOnClickListener(new OnClickListenerImpl());


    }

    private class OnClickListenerImpl implements View.OnClickListener {
        @Override
        //1.MEDIA_MOUNTED:SD卡正常挂载
        //2.Environment.getExternalStorageDirectory()获取外部存储路径(这里我想要说下,我有在网上
        // 看到朋友们说,除了SD卡以外,还会出现存储到手机内部存储中!!表示我还没有遇到这种情况······)
        //3.File.separator这个其实就是代表了“\”符号
        public void onClick(View v) {
            if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                return;
            }
            File file=new File(Environment.getExternalStorageDirectory().toString()
            +File.separator
            +"zsfdata"+File.separator+"member.xml");
            //4.file.getParentFile()返回此抽象路径名的父抽象路径名
            //5.mkdirs() 创建此抽象路径名,包括必要的和不存在的父目录的目录。
            //mkdirs()可以创建多层目录,如“F:\zz\ss\ff······”
            //mkdir()只可以创建单层目录,如“F:\zz”
            if(!file.getParentFile().exists()){
                file.getParentFile().mkdirs();//创建文件夹
            }
            //6想要读取文档,必须要有一个DocumentBuilder
            //建立DocumentBuilderFactory,用以取得DocumentBuilder
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=null;
            try {
                builder=factory.newDocumentBuilder();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            }
            //7.定义Document接口对象,通过DocumentBuider类进行DOM树的转换操作
            //Document 接口表示整个 HTML 或 XML 文档。从概念上讲,它是文档树的根,并提供对文档数据
            // 的基本访问。
            Document doc=null;
            doc=builder.newDocument();//建立一个新文档

            //8.建立各个操作节点
            //Element,接口。表示一个程序元素,比如包、类或者方法。每个元素都表示一个静态的语言级构造
            // (不表示虚拟机的运行时构造)。
            //元素应该使用 equals(Object) 方法进行比较。不保证总是使用相同的对象表示某个特定的元素。
           // 要实现基于 Element 对象类的操作,可以使用 visitor 或者使用 getKind() 方法的结果。
           /**
             *  Element createElement(String tagName)throws DOMException
             *  创建指定类型的元素。注意,返回的实例实现 Element 接口,所以可以直接在返回的对象上指定属性。
             *  此外,如果存在具有默认值的已知属性,则自动创建表示它们的 Attr 节点,并将其连接到该元素。
             *  要创建具有限定名称和名称空间 URI 的元素,使用 createElementNS 方法。
             */

            Element addresslist=doc.createElement("addresslist");
            Element linkman=doc.createElement("linkman");
            Element name=doc.createElement("name");
            Element email=doc.createElement("email");

            //9.设置节点的内容,即为每一个节点添加文本节点
            //定义和用法
            //appendChild() 方法在指定元素节点的最后一个子节点之后添加节点。
            //该方法返回新的子节点。
            //语法:appendChild(node);参数node,必须要追加的节点
            name.appendChild(doc.createTextNode(MainActivity.this.name.getText().toString()));
            email.appendChild(doc.createTextNode(MainActivity.this.email.getText().toString()));

            //10.设置节点关系
            linkman.appendChild(name);
            linkman.appendChild(email);
            addresslist.appendChild(linkman);
            doc.appendChild(addresslist);

            /**
             * TransformerFactory 实例可用于创建 Transformer 和 Templates 对象。
             确定要创建的哪一个 Factory 实现被命名为 "javax.xml.transform.TransformerFactory"
             的系统属性。此属性命名了 TransformerFactory 抽象类的一个具体子类。如果未定义此属性,
             则使用平台默认的属性。

             */
            /**Transformer类--此抽象类的实例能够将源树转换为结果树。
             可以通过 TransformerFactory.newTransformer 方法获取此类的实例。然后可以使用此实例处理
             来自不同源的 XML,并将转换输出写入各种接收器。
             在多线程同时运行时不能使用此类的对象。不同线程可以同时使用不同的 Transformers。
             Transformer 可以多次使用。可以在转换之间保留参数和输出属性。
             *
             */
            //11.输出文档到文件中
            TransformerFactory tf=TransformerFactory.newInstance();
            Transformer t=null;
            try {
                t=tf.newTransformer();
            } catch (TransformerConfigurationException e) {
                e.printStackTrace();
            }
            t.setOutputProperty(OutputKeys.ENCODING,"GBK");//设置转换的输出属性。
            //DOMSource类   以 Document Object Model(DOM)树的形式充当转换 Source 树的持有者。
            DOMSource source=new DOMSource(doc);
            StreamResult result=new StreamResult(file);//指定输出位置
            try {
                t.transform(source,result);
            } catch (TransformerException e) {
                e.printStackTrace();
            }
        }
    }
}

最后修改AndroidManifest.xml

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


到此我们的关于DOM解析就完成了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值