解析xml

xml解析的简介(重点)

sax解析的原理

  * 解析xml有两种技术   dom 和 sax

  * 根据xml的层级结构在内存中分配一个树形结构

  ** 把xml中标签、属性、文本封装成对象  

  sax方式:事件驱动,边读边解析

    * 在javax.xml.parsers包里面

      ** SAXParser

        此类的实例可以从 SAXParserFactory.newSAXParser()方法获取

        - parse(File f,DefaultHandler dh)

          * 两个参数

          ** 第一个参数:xml的路径

          ** 事件处理器

      ** SAXParserFactory

        实例newInstance()方法中获取

    * 分析sax执行的过程

      - 当解析开始标签时,自动执行startElement方法

      - 当解析到文本的时候,自动解析characters方法

      - 当解析到结束标签的时候,自动执行endElement方法

jaxp解析xml

使用jaxp的sax方式解析xml

  * sax方式不能实现增删改操作,只能做查询操作

  * 打印整个文档

  ** 执行parse方法,第一个参数是xml的路径,第二个参数是事件处理器

    * 创建一个类,继承事件处理器的类

    * 重写里面的三个方法

  ** 获取所有的name元素的值

    * 定义一个成员变量 flag = false

    * 判断开始方法是否是name元素,如果是name元素,把false改成true

    *如果flag值是true,在characters方法中打印内容

    * 当执行到结束方法的时候,把flag值设置为false

  ** 获取第一个name的值

    * 定义一个成员变量的值 idx=1

    * 在结束方法的时候,idx+1 idx++

    * 想要打印出第一个元素的值,

      - 在characters方法里面判断

      -- 判断flag=true 并且 idx=1,再打印内容

public class TestSax {

    public static void main(String[] args) throws Exception {
        // 创建解析器工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        // 创建解析器
        SAXParser saxParser = saxParserFactory.newSAXParser();
        // 执行parse方法
        saxParser.parse("src/person.xml", new MyDefault2());
    }

}

// 获取所有name元素的值
class MyDefault2 extends DefaultHandler {
    boolean flag = false;

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 判断qName是否是name元素
        if ("name".equals(qName)) {
            flag = true;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(flag == true) {
            System.out.println(new String(ch,start,length));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        //把flag设置成false,表示name元素结束
        if("name".equals(qName)) {
            flag = false;
        }
    }

}

// 打印整个文档的内容
class MyDefault1 extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.print("<" + qName + ">");
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.print(new String(ch, start, length));
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.print("</" + qName + ">");
    }
使用jaxp的sax方式解析xml

使用jaxp的dom方式解析xml

jaxp查询节点

private static void selectAll() throws Exception {
        // 创建解析器工厂
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        // 根据解析器工厂得到解析器
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        // 解析xml得到document
        Document document = builder.parse("src/person.xml");
        // 得到所有的name元素
        NodeList list = document.getElementsByTagName("name");
        // 遍历集合
        for (int i = 0; i < list.getLength(); i++) {
            Node name = list.item(i);
            String s = name.getTextContent();
            System.out.println(s);
        }
    }

jaxp添加节点

// 添加节点
    private static void addOne() throws Exception{
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = builderFactory.newDocumentBuilder();
    Document document = builder.parse("src/person.xml");
    NodeList list = document.getElementsByTagName("p1");
    Node p1 = list.item(0);
    Element sex = document.createElement("sex");
    Text text = document.createTextNode("nan");
    sex.appendChild(text);
    p1.appendChild(sex);
    //回写xml
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
    }

jaxp修改节点

  添加一个setTextContent方法即可

jaxp删除节点

  获取要删除节点的父节点,利用其父节点删除该节点,只要内容发生变化都必须回写xml

jaxp遍历节点

  获取节点的子节点,然后利用递归调用完成所有子节点的遍历

    // 遍历节点
    private static void listElement() throws Exception {
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document document = builder.parse("src/person.xml");
        // 编写一个方法来遍历节点
        list1(document);
    }

    private static void list1(Node node) {
        // 判断是元素类型才打印
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            System.out.println(node.getNodeName());
        }
        // 得到node下面的子节点
        NodeList list = node.getChildNodes();
        // 遍历list
        for (int i = 0; i < list.getLength(); i++) {
            // 得到lsit下面的节点
            Node node1 = list.item(i);
            // 使用递归调用实现继续得到子节点的方法
            list1(node1);
        }
    }

 dom4j解析XML

  * dom4j是一个组织,针对xml解析,提供解析器dom4j

  * dom4j不是javase的一部分,所以需要导包

  * 达到document

    SAXReader reader = new SAXReader();

    Document document = reader.read(url);

  * document的父节点是Node

    * 如果在document里面找不到想要的方法,到Node里面去找

  * document里面的方法 getRootElement()    获取到根节点 返回的是Element

  * Element也是一个接口,父接口是Node

    - Element和Node里面方法

      ** getParent()   添加父节点

      ** addElement  添加标签

  

 使用dom4j实现查询操作

    查询所有name元素里面的值

    1、创建解析器

    2、得到document

    3、得到根节点  getRootElement()    返回Element

    4、得到所有的p1标签

      * element("p1")  返回list集合

        ** 表示获取标签下面第一个子标签

        ** qname:标签的名称

      * element(qname)

        ** 获取标签下面的所有子标签

      * elements()

        ** 获取标签下面的所有的一层标签

    5、得到name

      * 在p1下面执行 element("name")方法  返回Element

    6、得到name里面的值

      * getText方法得到值

public class TestDom4j {

    public static void main(String[] args) throws Exception {
        selectName();
    }
    
    public static void selectName() throws Exception {
        //创建解析器
        SAXReader saxReader = new  SAXReader();
        //得到document
        Document document = saxReader.read("src/person.xml");
        //得到根节点
        Element root = document.getRootElement();
        //得到p1
        List<Element> list = root.elements();
        //便利list
        for(Element element : list) {
            Element name1 = element.element("name");
            String s = name1.getText();
            System.out.println(s);
        }
    }
}
使用dom4j查询xml

  查询第一个name元素的值

public static void selectOne() throws Exception {
        // 创建解析器
        SAXReader saxReader = new SAXReader();
        // 得到document
        Document document = saxReader.read("src/person.xml");
        // 得到根节点
        Element root = document.getRootElement();
        // 得到p1
        Element p1 = root.element("p1");
        // 得到第一个name
        Element name1 = p1.element("name");
        // 得到name1里面的值
        String s = name1.getText();
        System.out.println(s);
}
查询第一个name的值

 使用dom4j实现添加操作

  在第一个p1标签末尾添加一个元素<sex>nv</sex>

    

// 在第一个p1标签下添加一个sex元素
    public static void addSex() throws Exception {
        // 创建解析器
        SAXReader saxReader = new SAXReader();
        // 获取document
        Document document = saxReader.read("src/person.xml");
        // 得到根节点
        Element root = document.getRootElement();
        // 获取第一个p1
        Element p1 = root.element("p1");
        // 在p1下面添加元素
        Element sex = p1.addElement("sex");
        // 在添加之后的元素下面添加文本
        sex.addText("nv");
        // 回写xml
        OutputFormat format = OutputFormat.createPrettyPrint();//可以有缩进的效果
        XMLWriter xmlWrite = new XMLWriter(new FileOutputStream("src/person.xml"), format);
        xmlWrite.write(document);
        xmlWrite.close();
    }
使用dom4j实现添加操作

  在第一个p1标签下的age之前添加school标签

// 在第一个标签p1下面的age之前添加<school></school>
    public static void addSchool() throws Exception {
        // 创建解析器
        SAXReader saxReader = new SAXReader();
        // 获取document
        Document document = saxReader.read("src/person.xml");
        // 得到根节点
        Element root = document.getRootElement();
        // 得到第一个p1
        Element p1 = root.element("p1");
        // 获取第一个p1下面的所有元素
        List<Element> list = p1.elements();
        // // 获取p1下面的第一个age元素
        // Element age1 = p1.element("age");
        // // 获取age在列表里面的位置
        // int index = age1.indexOf(p1);
        // 创建一个school元素
        // Element school= document.addElement("school");
        Element school = DocumentHelper.createElement("school");
        // 创建文本
        school.setText("CDNU");
        // 在特定位置添加元素
        // list.add(index - 1, school);
        list.add(1, school);
        // 回写xml
        OutputFormat format = OutputFormat.createPrettyPrint();// 可以有缩进的效果
        XMLWriter xmlWrite = new XMLWriter(new FileOutputStream("src/person.xml"), format);
        xmlWrite.write(document);
        xmlWrite.close();
    }
在第一个p1标签下的age之前添加school标签

   dom4j里面封装方法的操作

  * 将得到document的操作和回写xml的操作封装成方法,还可将传递的文件路径封装成一个常量

public class dom4jUntils {
    
    public static final String PATH = "src/person.xml";
    
    //返回document
    public static Document getDocument(String path) {
        try {
            //创建解析器
            SAXReader reader = new SAXReader();
            //得到documen
            Document document = reader.read(path);
            return document;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    //回写xml的方法
    public static void xmlWriters(String path,Document document) {
        try {
        OutputFormat format = OutputFormat.createPrettyPrint();// 可以有缩进的效果
        XMLWriter xmlWrite = new XMLWriter(new FileOutputStream("src/person.xml"), format);
        xmlWrite.write(document);
        xmlWrite.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
dom4j里面的封装方法

   dom4j实现修改操作

  

// 修改第一个p1下面的age标签的值为33
    public static void modifyAge() throws Exception {
        Document document = dom4jUntils.getDocument(dom4jUntils.PATH);
        Element root = document.getRootElement();
        Element p1 = root.element("p1");
        Element age = p1.element("age");
        age.setText("33");
        dom4jUntils.xmlWriters(dom4jUntils.PATH, document);
    }

  dom4j实现获取标签属性值

// 获取p1标签id1的属性值
    public static void getAttribute() throws Exception {
        Document document = dom4jUntils.getDocument(dom4jUntils.PATH);
        Element root = document.getRootElement();
        Element p1 = root.element("p1");
        String value = p1.attributeValue("id1");
        System.out.println(value);
    }

dom4j支持XPATH的操作

  XPATH的简介

    * 可以支持获取到某个元素

    * 第一种形式

      /AAA/DDD/BBB  :表示一层一层的,AAA下面DDD下面的BBB

    * 第二种形式

      //BBB  :表示和这个名称相同,只要是BBB都得到

    * 第三种形式

      /*  :所有元素

    * 第四种形式

      BBB[1]  :表示第一个BBB元素

      BBB[last()]  :表示最后一个BBB元素

    * 第五种形式

      //BBB[@id]  :表示只要是BBB属性上面有id属性都得到

    * 第六种形式

      //BBB[@id='b1']  :元素名称是bbb,并且其id属性的值是b1

 *** dom4j提供两个方法,用来支撑XPATH

   -  selectNodes("xpath表达式");      获取多个节点

   -  selectsingleNode("xpath表达式");     获取单个节点     

  查询xml中所有name元素的值

    public static void getName() throws Exception {
        // 得到document
        Document document = dom4jUntils.getDocument(dom4jUntils.PATH);
        List<Node> list = document.selectNodes("//name");
        for (Node node : list) {
            String s = node.getText();
            System.out.println(s);
        }
    }

实现简单的学生管理系统

  * 使用xml当做数据库,存储学生信息

  * 创建一个xml文件,写一些学生信息

  

package cn.zzr.service;

import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import cn.cmlx.dom4jutils.dom4jUntils;
import cn.zzr.vo.Student;

public class StuService {
    //增加
    public static void addStudent(Student student) throws Exception {
        //创建解析器
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("src/student.xml");
        Element root = document.getRootElement();
        Element stu = root.addElement("stu");
        Element id1 = stu.addElement("id");
        Element name1 = stu.addElement("name");
        Element age1 = stu.addElement("age");
        id1.setText(student.getId());
        name1.setText(student.getName());
        age1.setText(student.getAge());
        //回写xml
        dom4jUntils.xmlWriters("src/student.xml", document);
    }
    
    //删除
    public static void delStudent(String id) throws Exception{ 
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("src/student.xml");
        Element root = document.getRootElement();
        //获取所有的id
        List<Node> list = root.selectNodes("id");
        for(Node node : list) {
            String idv = node.getText();
            if(idv.equals(id)) {
                Element stu = node.getParent();
                Element student = stu.getParent();
                student.remove(stu);
            }
        }
        //回写xml
        dom4jUntils.xmlWriters("src/student.xml", document);
    }
    //查找
    public static Student selStudent(String id) throws Exception{
        Student student = new Student();
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read("src/student.xml");
        //获取所有的id
        List<Node> list = document.selectNodes("//id");
        for(Node node : list) {
            String idv = node.getText();
            if(idv.equals(id)) {
                Element stu = node.getParent();
                String namev = stu.element("name").getText();
                String agev = stu.element("age").getText();
                student.setId(idv);
                student.setName(namev);
                student.setAge(agev);
            }
        }
        return student;
    }
}
StuService.java
package cn.zzr.vo;

public class Student {
    private String id;
    private String name;
    private String age;

    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 getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
    
}
Student.java
<?xml version="1.0" encoding="UTF-8"?>
<student>
    <stu>
        <id>111</id>
        <name>zq</name>
        <age>11</age>
    </stu>
    <stu>
        <id>222</id>
        <name>cmlx</name>
        <age>22</age>
    </stu>
</student>
student.xml
package cn.zzr.stutest;

import cn.zzr.service.StuService;
import cn.zzr.vo.Student;

public class StudentTest {

    public static void main(String[] args) throws Exception {
        // testAdd();
        // testDel();
        testSel();
    }

    public static void testAdd() throws Exception {
        Student student = new Student();
        student.setId("333");
        student.setName("zzr");
        student.setAge("33");
        StuService.addStudent(student);
    }

    public static void testDel() throws Exception {
        StuService.delStudent("333");
    }

    public static void testSel() throws Exception {
        Student stu = StuService.selStudent("111");
        System.out.println(stu.toString());
    }

}
StudentTest.java

 

posted @ 2018-07-22 09:27  cmlx  阅读(213)  评论(0)    收藏  举报