Java——XMLl解析

---恢复内容开始---

本文章讲解四种 XML 解析方式 :

  DOM 和 SAX 为 Java提供的对 XML 解析的方式,不需要导入 jar 包

  DOM4J 和 JDOM 是其他组织使用他们自己的方式解析 XML 文件,需要我们导入一些 jar 包

首先我们先看一下 XML 文件

<School>         -----       父节点
    <student id="1">     ---- 子节点
        <name>小红</name>      ---  这个是student的子节点
        <age>18</age>
        <sex>女</sex>
        <address>北京海定区五道口</address>
    </student>
    <student id="2">      ----    子节点
        <name>小明</name>
        <age>19</age>
        <sex>男</sex>
        <address>北京海定区上地</address>
    </student>
</School>

下面的4种方法统一用上面的 XML 文件

第一种  DOM 解析 XML:

import java.io.IOException;

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

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Test {

    public static void main(String[] args) {
        //创建一个 DocumentBuilderFactory 对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            //创建DocumentBuilder对象
            DocumentBuilder db = dbf.newDocumentBuilder();
            //通过DocumentBuilder的pares方法加载student.xml文件到当前项目下
            Document document = db.parse("School.xml");
            //获取所有 School  下的子节点的集合
            NodeList nodeList = document.getElementsByTagName("student");
            //获取nodeList的长度
            //System.out.println(nodeList.getLength());
            for(int i = 0 ; i < nodeList.getLength() ; i++){

                System.out.println("**************第"+(i+1)+"名学生***************");

                //通过item(i) 获取一个student节点,nodeList的索引值从 0 开始
                Node stu = nodeList.item(i);

                /**
                 * 第一种不知道student节点的属性和个数
                 */
                //获取 student 的所有属性集合
                /*NamedNodeMap attrs = stu.getAttributes();
                for (int j = 0; j < attrs.getLength(); j++) {

                    Node attr = attrs.item(j);
                    System.out.println("属性名:\t"+attr.getNodeName());
                    System.out.println("属性值:\t"+attr.getNodeValue());
                }*/

                /**
                 * 第二种 知道 student 节点的有且自能有一个 id 属性
                 */
                //将student节点进行强制类型转换,转换为Element类型
                /*Element stu = (Element)nodeList.item(i);
                //通过 getAttribute("id") 方法获取属性值
                String attribute = stu.getAttribute("id");
                System.out.println("id的属性值为:"+attribute);*/

                //获取 student 所有子节点的集合
                NodeList childNodes = stu.getChildNodes();

                for (int j = 0; j < childNodes.getLength(); j++) {
                    Node node = childNodes.item(j);

                    //区分出 text 类型的node 以及 element 下来的 node
                    if(node.getNodeType() == Node.ELEMENT_NODE){

                        //判断获取到的此节点的名称是否等于name
                        if(node.getNodeName().equals("name")){ 

                            //System.out.println("姓名:\t"+node.getFirstChild().getNodeValue());
                            System.out.println("姓名:\t"+node.getTextContent());
                            /**
                             * 说一说这两个的区别
                             *  node.getFirstChild().getNodeValue() 获取一个子节点的值     并且该节点下不存在子节点,否则返回 null
                             *  node.getTextContent()  返回此节点下的所有后代 文本内容
                             */
                        }

                    }
                }
            }

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

第二种 SAX 解析 XML :

>>创建一个学生类用于接收解析的值
public class Student {

    private int id;
    private String name;
    private int age;
    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 getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

》》创建一个ASXParserHandler 类继承 DefaultHandler 类

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

public class SAXParserHandler extends DefaultHandler {

    private int index=0;
    private String value=null;
    private Student stu = null;
    //为了存储Student 对象
    private List<Student> list = new ArrayList<Student>();
    public List<Student> getList() {
        return list;
    }
    /**
     * 标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        //System.out.println("SAX解析开始");
    }
    /**
     * 标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        //System.out.println("SAX解析结束");
    }

    /**
     * 解析 XML元素的
     */
    @Override
    public void  startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        //调用 DefaultHandler 类的 startElement 方法
        super.startElement(uri, localName, qName, attributes);

        //开始解析 student元素的属性
        if (qName.equals("student")) {
            stu = new Student();
            //index++;    //记录学生 id
            //System.out.println("===========开始遍历第"+index+"名学生的信息=============");
            //已知Student 元素下的属性名称,根据属性名称获取属性值
            /*String vaule = attributes.getValue("id");
            System.out.println(vaule);*/
            //不知到 Student 元素下的属性名称和个数
            for (int i = 0; i < attributes.getLength(); i++) {
                /*System.out.print("属性名称:"+attributes.getQName(i));
                System.out.print("----属性值:"+attributes.getValue(i));*/
                if (attributes.getQName(i).equals("id") ){
                    stu.setId(Integer.parseInt(attributes.getValue(i)));
                }
            }
        }else if (!qName.equals("School")){
            /*System.out.print("\n节点名是:"+qName);*/
        }
    }

    /**
     * 为了遍历xml结束标签   比如这样的  </name>
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(uri, localName, qName);
        if (qName.equals("student")) {
            //把学生对象添加到集合当中
            list.add(stu);
            //System.out.println("\n============结束遍历第"+index+"名学生的信息============");
        }else if (qName.equals("name")) {
            stu.setName(value);
        }
    }
    /**
     * 解析 XML中的内容
     */

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);

        value = new String(ch,start,length);
        /*if(!value.trim().equals("")){
            System.out.print("----属性值是:"+value);
        }*/

    }

}

》》 解析类

public static void main(String[] args) {
        //1.通过SaxParserfactory的newInstance()方法获取一个 SAXParserFactory 实例
        SAXParserFactory factory = SAXParserFactory.newInstance();

        try {
            //2.通过 factory 获取 SAXParser 实例
            SAXParser parser = factory.newSAXParser();

            //创建SAXParserHandler 对象
            SAXParserHandler handler = new  SAXParserHandler();
            //3.
            parser.parse("School.xml", handler);

            for (Student item : handler.getList()) {
                System.out.println(item.getName());
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

送上SAX解析 XML 图一副:

第三种 JDOM 解析XML :

  准备工作:

    导入 Jar 包 jdom2-2.0.5.jar

    下载地址:http://maven.outofmemory.cn/org.jdom/jdom2/2.0.5/

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class JDOMTest {

    public static void main(String[] args) {
        //1.创建一个SAXBuilder 对象
        SAXBuilder saxBuilder =new SAXBuilder();
        //创建一个 InputStream 对象
        InputStream is;
        try {
            //创建一个输入流,将 XML 文件加载到输入流
            is = new FileInputStream("School.xml");
            //当出现乱码情况,首先看 XML 当中的 encoding 是不是 utf-8
            //不改变XML encoding 情况下,通过代码防止中文乱码
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            //通过saxBuilder的build方法,将输入流加载到 saxBuilder中
            Document document = saxBuilder.build(isr);
            //通过 getRootElement 方法获取 XML 的根节点
            Element element = document.getRootElement();
            //获取跟节点下的子节点的集合
            List<Element> stuList = element.getChildren();

            for (Element item : stuList) {
                System.out.println("开始遍历第"+ (stuList.indexOf(item) + 1) +"一个学生的信息");
                //获取student 属性集合
                /*List<Attribute> attributes = item.getAttributes();
                for (Attribute attribute : attributes) {
                    System.out.print("属性名:"+attribute.getName());
                    System.out.println("\t属性值:"+attribute.getValue());
                }*/
                //对 Student节点的子节点以及节点值遍历
                List<Element> children = item.getChildren();
                for (Element stu : children) {
                    if (stu.getName().equals("name")) {
                        System.out.println("姓名是:"+stu.getValue());
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (JDOMException | IOException e) {
            e.printStackTrace();
        }
    }
}

第四种DOM4解析XML:

  准备工作:

  导入 jar 包 :dom4j-1.6.jar

  下载地址:

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Dom4jTest {

    public static void main(String[] args) {
        //创建一个 SAXReader 对象
        SAXReader reader = new SAXReader();
        try {
            //通过 reader 对象的 read 方法加载 School.XML文件
            Document document = reader.read(new File("School.xml"));
            //通过document 对象 获取根节点
            Element school = document.getRootElement();
            //通过 Element 对象的 elementIterator 方法获取迭代器
            Iterator it = school.elementIterator();
            //遍历迭代器,获取根节点中的信息
            while(it.hasNext()){
                //获取到根节点下的一个子节点
                Element student = (Element) it.next();
                //获取子节点的属性名以及属性值
                List<Attribute> list = student.attributes();
                for (Attribute attribute : list) {
                    //打印属性名称以及属性值
                    System.out.println("属性名:"+attribute.getName()+"\t属性值:"+attribute.getValue());
                }
                //获取 跟节点下的一个子节点 的所有节点集合
                Iterator itt = student.elementIterator();
                //开始遍历这个节点的集合
                while(itt.hasNext()){
                    //得到每一节点
                    Element studenChild = (Element)itt.next();
                    //打印节点名称以及节点值
                    System.out.println("节点名称:"+studenChild.getName()+"\t节点值:"+studenChild.getStringValue());
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

性能比较:

DOM :

  优点:

  1.形成了树结构,只观好理解,代码更容易编写

  2.解析过程中树结构保留内存中,方便修改

  缺点:

  1.当 XML 文件较大时,对内存耗费比较大,容易影响解析性能并造成内存溢出

SAX:

  优点:

  1.采用事件驱动模式,对内存耗费比较小

  2.适用于只需处理 XML 中数据时

缺点:

  1.不宜编码

  2.很难同时访问同一个 XML中的多处不同数据

JDOM:

  1.仅仅使用具体类而不使用接口           简化了API 限制了JDOM 的灵活性

  2.API 大量使用了 Collections 类

DOM4J:

  1.JODM 的一种智能分支,它合并了许多超出基本XML 文档表示功能

  2.DOM4J使用接口和抽象基本类方法,是一个优秀的Java XNL API

  3.具有性能优异、灵活性好、功能强大和极端易用使用特点

  4.是一个开放源代码的软件

 

  

时间: 2024-11-14 02:16:52

Java——XMLl解析的相关文章

JAVA - Sql解析工具fdb-sql-parser简单使用

由于想要解决Mybatis分页插件中count查询效率问题,因为order by很影响效率,所以需要一种方式处理sql,将order by 语句去掉. 试了好几个sql解析工具,最后选择了fdb-sql-parser. Maven依赖: <dependency> <groupId>com.foundationdb</groupId> <artifactId>fdb-sql-parser</artifactId> <version>1.

java dom4j解析xml实例(2)

java利用dom4j解析xml 需要的jar包: dom4j官方网站在 http://www.dom4j.org/ 下载dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要加入包jaxen-1.1-beta-7.jar(如果不导入这个架包程序可以执行出结果,但最后会报异常) 将相关jar包引入后,实际解析操作如下:  1.要解析的xml文件province.xml: <china dn="d

org.w3c.dom(java dom)解析XML文档

位于org.w3c.dom操作XML会比较简单,就是将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效果可能会不理想 首先来了解点Java DOM 的 API:1.解析器工厂类:DocumentBuilderFactory 创建的方法:DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 2.解析器:DocumentBuilder 创建方法:通过解析器工厂类来获得 DocumentBu

java XML解析

package com.kpsh.myself; import java.io.File;import java.io.FileInputStream;import java.util.List; import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory; import org.dom4j.Document;import org.dom4j.DocumentHelper;imp

JAVA SAX解析XML文件

[代码] [Java]代码view sourceprint?001package SAXparse;002 003 004import java.io.FileInputStream;005import java.lang.reflect.Array;006import java.lang.reflect.InvocationTargetException;007import java.lang.reflect.Method;008import java.text.ParseException;

Java XML解析技术

XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已.基本的解析方式有两种,一种叫SAX,另一种叫DOM. DOM的全称是Document Object Model,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作.通过DOM接口,应用程

Java泛型解析(04):约束和局限性

Java泛型解析(04):约束和局限性 前两节,认识和学习了泛型的限定以及通配符,初学者可能需要一些时间去体会到泛型程序设计的好处和力量,特别是想成为库程序员的同学就需要下去体会通配符的运用了,应用程序员则需要掌握怎么使用泛型,这里针对泛型的使用中的约束和局限性做一个介绍性的讲解. 不能用基本类型实例化类型参数 这个很好理解,实例化泛型类时泛型参数不能使用基本类型,如List<int>这是不合法的,要存储基本类型则可以利用基本类型的包装类如List<Integer> .List&l

Java泛型解析(03):虚拟机执行泛型代码

Java泛型解析(03):虚拟机执行泛型代码 Java虚拟机是不存在泛型类型对象的,所有的对象都属于普通类,甚至在泛型实现的早起版本中,可以将使用泛型的程序编译为在1.0虚拟机上能够运行的class文件,这个向后兼容性后期被抛弃了,所以后来如果用Sun公司的编译器编译的泛型代码,是不能运行在Java5.0之前的虚拟机的,这样就导致了一些实际生产的问题,如一些遗留代码如何跟新的系统进行衔接,要弄明白这个问题,需要先了解一下虚拟机是怎么执行泛型代码的. 虚拟机的一种机制:擦除类型参数,并将其替换成特

Java Sax解析xml

1.   Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode.如下面的这段book.xml Xml代码   <?xml version="1.0" encoding="UTF-8"?> <books> <book id="12"> <name>thinking in java<