如春天的轻轻微风般带你解读如何解析xml文件(二)

于首先,小芳声想明一下,这篇内容也是针对对java语言有一定基础,对xml解析有一点知晓的小伙伴们!请谅解!
首先,给大家看一看我写的一个简单的xml文件的内容

<?xml version="1.0" encoding="UTF-8"?>
/*在这里说一下标签的形式
<根标签>
    <子标签1>
        <孙标签1>
            <孙标签2>
                ......
            </孙标签2>
        </孙标签1>
    </子标签1>
    <子标签2>
    </子标签2>
</根标签>
可以看出子标签都是在一个根标签中包含的,而子标签的层次由需求决定,
xml文件里面的标签都是自定义的并且没有特定的名称,但是在这里小芳建议写标签时,最好写与这个层次有的关系的名称,例如:
<student-list>  //学生列表
    <student>  //其子标签就是学生
        <id> //关于学生的一些具体属性
        </id>
        ...
    </student>
</student-list>
这样一方面标签名称很清楚,提高代码的可读性;另一方面,也可以作为开发人员的一种素养吧!
   */
<student-list>
    <student id="201704005001" name="张三丰" 
            people-id="987456321456321789" sex="m" introduce="古代神人">
        <hobby>睡觉</hobby>
        <hobby>打盹</hobby>
    </student>
    <student id="201704001001" name="你很好" 
            people-id="123456766666666666" sex="m" introduce="现代帅哥">
        <hobby>学习</hobby>
        <hobby>做题</hobby>
        <hobby>撸代码</hobby>
    </student>
    <student id="201704001002" name="她很好" 
            people-id="123456789123456789" sex="f" introduce="小美女">
        <hobby>美容</hobby>
        <hobby>购物</hobby>
        <hobby>追星</hobby>
        <hobby>打豆豆</hobby>
    </student>
</student-list>

为了方便存储这些数据,我们建立一个XMLModel类,这个类主要用于存放数据。具体代码如下:

package com.mec.XMLParser.model;

import java.util.ArrayList;
import java.util.List;

public class XMLModel {
    //根据xml的名称,对这个类创建成员
    private String id; 
    private String name;
    private String peopleId;
    private String sex;
    private String introduce;
    private List<String> hobbys;//因为爱好不止一个,所以用数组

    public XMLModel() {
        //无参构造,初始化hobbys这个对象,具体为什么在这里实例化?习惯
        hobbys = new ArrayList<>();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPeopleId() {
        return peopleId;
    }

    public void setPeopleId(String peopleId) {
        this.peopleId = peopleId;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getIntroduce() {
        return introduce;
    }

    public void setIntroduce(String introduce) {
        this.introduce = introduce;
    }
    //添加爱好的方法
    public void addHobby(String hobby) {
        if(hobby == null) {
            return;
        }
        hobbys.add(hobby);
    }
    //移除爱好的做法
    public void removeHobby(){
        hobbys.clear();
    }


    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[" + id + "]");
        builder.append(":" + peopleId);
        builder.append(", " + name);
        builder.append(", " + (sex.equals("m") ? "男" : "女"));
        builder.append(", " + introduce);
        builder.append(",(");
        //底下八行代码是为了处理多个爱好的显示,最后一个爱好的最后不能加逗号
        int index = 0;
        for(String hobby : hobbys) {
            builder.append(hobby);
            if(index < hobbys.size()-1) {
                builder.append(",");
                index++;
            }
        }
        builder.append(")");
        return builder.toString();
    }
}

好了,写到这里猜到了最关键的地方,那就是如何解析它?如下:

package com.mec.parserXML;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.mec.XMLParser.model.XMLModel;

public class XMLParser {

    public static void main(String[] args) {
        //创建一个 XMLModel的对象,便于设置学生的属性
        XMLModel model = new XMLModel();
        //用IO流得到这个文件,这里要注意路径问题,我的文件直接放在scr(默认根目录下)底下的
        InputStream inputStream = XMLParser.class.getResourceAsStream("/my_first_xml.xml");
        System.out.println(inputStream);
        //创建一个文件工厂的实例,这里注意它在实例化时不能用new关键字
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //底下两行可以类比,把文件放进工厂,要找一个部门处理这个文件,找到部门之后,还要找一个具体的人负责它,是一种层层深入的关系,仔细想想就想通了
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse(inputStream);
            //底下的一句是得到根标签,接收它的类是一个NodeList类型的对象 
            NodeList studentList = document.getElementsByTagName("student-list");
            //底下的一句话是获取这个数组的第一个元素(也就是<student-list>它自己),因为在小芳的xml文件中,这个studentList 的长度为1
            Element stuEle = (Element) studentList.item(0); 
            System.out.println(stuEle);
            System.out.println("studentList.getLength()" + studentList.getLength());
            //底下的这句话是得到根标签低下的子标签,即<student>
            NodeList studentsList =  stuEle.getElementsByTagName("student");
            System.out.println("studentsList.getLength():" + studentsList.getLength());
            //大家可以看到,<student>这个标签不止一个,所以要遍历它由此取得每个<student></student>中的属性(包含子标签的内容以及在它标签内部的属性)
            for(int studentsListIndex = 0; studentsListIndex < studentsList.getLength();studentsListIndex++) {
                //取得它下标为index的标签
                Element studentEle = (Element) studentsList.item(studentsListIndex);
                //底下四行是获取<tudent>标签内部的属性
                model.setId(studentEle.getAttribute("id"));
                model.setName(studentEle.getAttribute("name"));
                model.setPeopleId(studentEle.getAttribute("people-id"));
                model.setSex(studentEle.getAttribute("sex"));
                model.setIntroduce(studentEle.getAttribute("introduce"));
                //由于hobby的标签不止一个,所以对它的处理有点特别,但是还是遵循层层深入的原则,这里要注意的是程序执行完了以后再输出的话,第二个人会输出他自己和第一个人的爱好,而最后一个人会输出所有学生全部的爱好,由此,小芳在XMLModel中定义的removeHobby()方法发挥了作用,但是又有一点要注意,就是这个方法调用的时机,请往下看
                //得到<hobby>标签的列表
                NodeList hobbyList = studentEle.getElementsByTagName("hobby");
                for(int hobbyIndex = 0; hobbyIndex < hobbyList.getLength();hobbyIndex++) {
                    Element hobbyText = (Element) hobbyList.item(hobbyIndex);
//获取并在model添加这个爱好               model.addHobby(hobbyText.getTextContent());
                }
                //这两句话不可颠倒,若颠倒了则输出的爱好为“()”,若去掉,则在还没有输出之前就将爱好全部清空了,而我们的目的是输出后一个人时,删除前一个人的爱好;在输出model时会默认调用它的toString()方法
                System.out.println(model);
                model.removeHobby();
            }

        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

java.io.BufferedInputStream@379619aa
[student-list: null]
studentList.getLength():2
studentsList.getLength():3
[201704005001]:987456321456321789, 张三丰, 男, 古代神人,(睡觉,打盹)
[201704001001]:123456766666666666, 你很好, 男, 现代帅哥,(学习,做题,撸代码)
[201704001002]:123456789123456789, 她很好, 女, 小美女,(美容,购物,追星,打豆豆)

小芳在这里总结以下几点:
1.xml中每个标签都是一个元素(Element类型),而且获取属性的方法是针对Element类型的对象才有的方法;
2.从document中获取文本内容时是以NodeList的类型接收的;
3.一定要注意层次关系,每次取出数据之后都要都要测试,以免出现错误,事与愿违;
4.要细心,处理好细节问题。
好了,谢谢你还能看到这里!
晚安!
我想每天都像它一样开心!每天进步一点点,只是为了不让自己讨厌自己!嗯,就这么简单!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值