欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 16:59:25
...

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找节点。

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

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();
    }

}

运行结果:

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


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);
    }
}

运行结果:

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

测试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");

运行结果:

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


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();
    }

}

运行结果:
张三
李四
王五

相关标签: xml