XML--jdom/dom4j/sax解析XML文件

XML

1.XML(extensible markup language ):可扩展标记语言。

2.XML特点是,标签可以由用户自己随意扩展。比如,html中标签如何写,属性如何写,属性值如何写,都是有规范的(w3c规定的)。但是在xml文件中,标签没有规范,可以随意扩展。

3.XML文件有两个作用:
(1)做其它技术的配置文件:

<config>
   <nav>
     <color>red</color>
    <size>5</size>
   </nav>
<body>
     <color>red</color>
    <size>5</size>
   </body>
<foot>
     <color>red</color>
<color>blue</color>
<color>green</color>
    <size>5</size>
   </ foot >
</config>

(2)在不同语言环境下交换数据:

中国人–>中国话–>人–>韩语—>韩国人
中国人–>中国话–>人–>日语—>日本人
XXX国人—>英语—>YYY国人
这就有一个要求,所有国家的人,都要学习英语。

Java程序–>java结果 –> 人—>C参数–> C语言
Java程序–>java结果 –> 人—>php参数–> php程序
Java程序–>java结果 –> 人—>asp参数–>asp程序
C程序–>C结果–>人–>php参数–>php程序
XXX程序–> xml –>YYY程序
这就有一个要求,所有的编程语言都要支持xml。
a)支持向xml中写数据
b)支持从xml中读取数据


解析XML文件

1.每个浏览器都会根据html文档,解析出一个DOM对象。
Document代表整棵树,document.getElementByTd()就是在这棵树上根绝id找节点。

这里写图片描述

2.所有后缀为xml的文件都必须写的<?xml version="1.0" encoding="utf-8"?>,它的作用就是告诉程序,xml版本是多少,使用什么编码表。

3.自己编写的xml文件其他内容,完全是自己扩展出来的标签。

4.我们有3种解析xml文件的方式:
jdom dom4j sax

5.解析XML文件的工具可以分为两大类:
(1)将xml解析为一棵树:jdom dom4j…
优点:

这种解析方式,可以随时访问一棵树上的任意一个节点。

缺点:

这种方式需要把整个xml文件的内容加载到内存中,然后才创建dom。如果xml文件的内容特别大,超过58M,就会内存溢出。

(2)将xml不解析为一棵树,而是从上向下扫描:sax
优点:

不会加载整个xml文件到内存中,而是局部加载,扫描到哪里,就加载到哪里,解析到哪里。

缺点:

不会随时随地任意访问xml文件的任意节点,不会修改xml文件(不能添加节点,删除节点,修改节点)。


jdom解析XML文件

其实,安装好jdk以后,jdk自带的API就有能XML的API,但是Java自带的API操作再来太麻烦,所以出现了jdom,jdom是对原声Java解析XML API的封装,操作起来更简单方便。

jdom解析XML文件具体步骤可以参考下面这个例子
1.XML文件中写:
student.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE students SYSTEM "students.dtd">
<students>
    <student>
        <id>1</id>
        <name>张三</name>
        <age unit="岁">20</age>
    </student>
    <student>
        <id>2</id>
        <name>李四</name>
        <age unit="岁">30</age>
    </student>
    <student>
        <id>3</id>
        <name>王五</name>
        <age unit="岁">40</age>
    </student>
</students>

2.dtd文件:一套为了进行程序间的数据交换而建立的关于标记符的语法规则。
student.dtd:

<!ELEMENT students (student*) >
<!ELEMENT student (id,name,age) >
<!ELEMENT id (#PCDATA) > 
<!ELEMENT name (#PCDATA) > 
<!ELEMENT age (#PCDATA) >
<!ATTLIST age unit CDATA #REQUIRED> 

3.利用jdom解析上面那个student.xml文件:

package com.westos.jdom;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

public class App {

    public static void find() throws Exception {
        // 创建一个解析器
        SAXBuilder sb = new SAXBuilder();
        // 打开验证模式
        sb.setValidation(true);
        // 用解析器来解析一个xml文件,得到一个Document对象,此时树已经生成
        Document document = sb.build(new File("src/students.xml"));
        // 通过document对象,可以获取根对象
        Element root = document.getRootElement();
        // 再从根对象中获取所有子节点
        List<Element> list = root.getChildren();
        for (Element elt : list) {
            System.out.println("===================================");
            System.out.println(elt.getName());
            Element id = elt.getChild("id");
            Element name = elt.getChild("name");
            Element age = elt.getChild("age");
            System.out.println("id:" + id.getText());
            System.out.println("name:" + name.getText());
            System.out.println("age:" + age.getText() + age.getAttribute("unit").getValue());
        }
    }

    public static void save() throws Exception {
        SAXBuilder sb = new SAXBuilder();
        Document document = sb.build(new File("src/students.xml"));
        Element root = document.getRootElement();
        List<Element> list = root.getChildren();

        Element student = new Element("student");
        Element id = new Element("id");
        Element name = new Element("name");
        Element age = new Element("age");

        Attribute unit = new Attribute("unit", "岁");
        Attribute aaa = new Attribute("aaa", "bbb");
        age.setAttribute(unit);
        age.setAttribute(aaa);

        id.setText("5");
        name.setText("马青青");
        age.setText("25");
        student.addContent(id);
        student.addContent(name);
        student.addContent(age);
        list.add(student);

        // 存盘
        XMLOutputter xmlout = new XMLOutputter();
        xmlout.output(document, new FileOutputStream(new File("src/students.xml")));

    }


    public static void update() throws Exception {
        SAXBuilder sb = new SAXBuilder();
        Document document = sb.build(new File("src/students.xml"));
        Element root = document.getRootElement();
        List<Element> list = root.getChildren();

        // 把id为4的学生,名字改为赵六
        for (Element elt : list) {
            Element id = elt.getChild("id");
            if("4".equals(id.getText())) {
                Element name = elt.getChild("name");
                Element age = elt.getChild("age");
                name.setText("赵六");
                age.setText("40");
            }
        }

        // 存盘
        XMLOutputter xmlout = new XMLOutputter();
        xmlout.output(document, new FileOutputStream(new File("src/students.xml")));

    }


    public static void delete() throws Exception {
        SAXBuilder sb = new SAXBuilder();
        Document document = sb.build(new File("src/students.xml"));
        Element root = document.getRootElement();
        List<Element> list = root.getChildren();

        // 把id为4的学生,删除掉
        Element del = null;
        for (Element elt : list) {
            Element id = elt.getChild("id");
            if("3".equals(id.getText())) {
                del = elt;
                break;
            }
        }

        list.remove(del);

        // 存盘
        XMLOutputter xmlout = new XMLOutputter();
        xmlout.output(document, new FileOutputStream(new File("src/students.xml")));

    }



    public static void main(String[] args) throws Exception {
        find();
    }

}

运行结果:

这里写图片描述


dom4j解析XML文件

jdom能完成什么功能,dom4j也能完成,但是dom4j还支持强大的XPath。

dom4j解析XML文件具体步骤可以参考下面这个例子
1.XML文件中写:
student.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE students SYSTEM "students.dtd">
<students>
    <student>
        <id>1</id>
        <name>张三</name>
        <age unit="岁">20</age>
    </student>
    <student>
        <id>2</id>
        <name>李四</name>
        <age unit="岁">30</age>
    </student>
    <student>
        <id>3</id>
        <name>王五</name>
        <age unit="岁">40</age>
    </student>
</students>

2.dtd文件中写:
student.dtd:

<!ELEMENT students (student*) >
<!ELEMENT student (id,name,age) >
<!ELEMENT id (#PCDATA) > 
<!ELEMENT name (#PCDATA) > 
<!ELEMENT age (#PCDATA) >
<!ATTLIST age unit CDATA #REQUIRED> 

3.利用jdom解析上面那个student.xml文件:

package com.westos.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.DefaultElement;


public class App {

    public static void find() throws Exception {
        // 创建解析器
        SAXReader sr = new SAXReader();
        // 使用解析器去解析一个xml文件,得到一个Document对象
        Document document = sr.read(new File("src/students.xml"));
        // 获取根元素,根据根元素获取所有子节点
        Element root = document.getRootElement();
        List<Element> list = root.elements();
        for (Element stu : list) {
            System.out.println("=================================");
            System.out.println(stu.getName());
            Element id = stu.element("id");
            Element name = stu.element("name");
            Element age = stu.element("age");
            Attribute unit = age.attribute("unit");
            System.out.println("id:" + id.getText());
            System.out.println("name:" + name.getText());
            System.out.println("age:" + age.getText() + unit.getValue());
        }
    }

    public static void save() throws Exception {
        // 创建解析器
        SAXReader sr = new SAXReader();
        // 使用解析器去解析一个xml文件,得到一个Document对象
        Document document = sr.read(new File("src/students.xml"));
        // 获取根元素,根据根元素获取所有子节点
        Element root = document.getRootElement();
        List<Element> list = root.elements();
        // 添加一个新学生
        Element stu = new DefaultElement("student");
        Element id = new DefaultElement("id");
        Element name = new DefaultElement("name");
        Element age = new DefaultElement("age");
        age.setAttributeValue("unit", "岁");

        id.setText("11");
        name.setText("php门徒");
        age.setText("24");
        stu.add(id);
        stu.add(name);
        stu.add(age);
        list.add(stu);

        // 存盘
        OutputFormat formatter = OutputFormat.createPrettyPrint();
        XMLWriter xWriter = new XMLWriter(new FileOutputStream(new File("src/students.xml")), formatter);
        xWriter.write(document);
    }



    public static void update() throws Exception {
        // 创建解析器
        SAXReader sr = new SAXReader();
        // 使用解析器去解析一个xml文件,得到一个Document对象
        Document document = sr.read(new File("src/students.xml"));
        // 获取根元素,根据根元素获取所有子节点
        Element root = document.getRootElement();
        List<Element> list = root.elements();
        // 把id为11的学生,名字改为php骨灰级玩家
        for (Element stu : list) {
            Element id = stu.element("id");
            if("11".equals(id.getText())) {
                Element name = stu.element("name");
                name.setText("php骨灰级玩家");
                break;
            }
        }

        // 存盘
        OutputFormat formatter = OutputFormat.createPrettyPrint();
        XMLWriter xWriter = new XMLWriter(new FileOutputStream(new File("src/students.xml")), formatter);
        xWriter.write(document);
    }

    public static void delete() throws Exception {
        // 创建解析器
        SAXReader sr = new SAXReader();
        // 使用解析器去解析一个xml文件,得到一个Document对象
        Document document = sr.read(new File("src/students.xml"));
        // 获取根元素,根据根元素获取所有子节点
        Element root = document.getRootElement();
        List<Element> list = root.elements();
        // 把id为10的学生,删除
        int size = list.size();
        for (int i = 0; i < size; i++) {
            Element stu = list.get(i);
            Element id = stu.element("id");
            if("10".equals(id.getText())) {
                list.remove(stu);
                break;
            }
        }


        // 存盘
        OutputFormat formatter = OutputFormat.createPrettyPrint();
        XMLWriter xWriter = new XMLWriter(new FileOutputStream(new File("src/students.xml")), formatter);
        xWriter.write(document);
    }
}

运行结果:

这里写图片描述

测试dom4j的XPath(Xml Path)
1.foo.xml:

<?xml version="1.0" encoding="utf-8"?>
 <AAA> 
          <BCC> 
               <BBB/> 
               <BBB/> 
               <BBB/> 
          </BCC> 
          <DDB> 
               <BBB/> 
               <BBB/> 
          </DDB> 
          <BEC> 
               <CCC/> 
               <DBD/> 
          </BEC> 
     </AAA> 

2.testXPath方法:

public static void testXPath() throws Exception {
        // 创建解析器
        SAXReader sr = new SAXReader();
        // 使用解析器去解析一个xml文件,得到一个Document对象
        Document document = sr.read(new File("src/foo.xml"));
        // 使用XPath技术,不需要获取根节点,而是直接调用document的一个api: selectNodes
        List<Element> list = document.selectNodes("//*[contains(name(),'C')]");
        for (Element elt : list) {
            System.out.println(elt.getName());
        }

//      List<Attribute> list = document.selectNodes("//@id");
//      for (Attribute elt : list) {
//          System.out.println(elt.getName() + ":" + elt.getValue());
//      }

        System.out.println("over");

运行结果:

这里写图片描述


sax解析XML文件

还是解析上面那个student.xml文件。

package com.westos.sax;

import java.io.File;
import java.io.FileInputStream;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.xerces.jaxp.SAXParserFactoryImpl;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;




public class App {

    public static void find() throws Exception {
        // 创建解析器
        SAXParserFactory spf = new SAXParserFactoryImpl();
        SAXParser sp = spf.newSAXParser();
        XMLReader reader = sp.getXMLReader();

        // 设置事件
        reader.setContentHandler(new DefaultHandler(){
            private String tag;
            // 碰到标记开始
            public void startElement(String uri, String localName,
                    String qName, Attributes attributes) throws SAXException {
                // System.out.println(qName+"开始");
                tag = qName;
            }
            // 碰到内容开始
            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                if("name".equals(tag)) {
                    System.out.println(new String(ch,start,length));
                }
            }
            // 碰到结束标记开始
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
                // System.out.println(qName+"结束");

            }
        });


        // 使用解析器,去解析一个xml文件, 此时没有Document生成
        reader.parse("src/students.xml");


    }

    public static void main(String[] args) throws Exception {
        find();
    }

}

运行结果:
张三
李四
王五

猜你喜欢

转载自blog.csdn.net/yangruxi/article/details/76208662