码迷,mamicode.com
首页 > 编程语言 > 详细

Java——XMLl解析

时间:2017-09-16 13:34:40      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:影响   nod   sax   情况   ges   stack   qname   存在   instance   

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

本文章讲解四种 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.是一个开放源代码的软件

 

  

Java——XMLl解析

标签:影响   nod   sax   情况   ges   stack   qname   存在   instance   

原文地址:http://www.cnblogs.com/szj-ang/p/7486133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!