zoukankan      html  css  js  c++  java
  • JAXP进行DOM和SAX解析

    1.常用XML的解析方式:DOM和SAX

    1)DOM思想:将整个XML加载内存中,形成文档对象,所以对XML操作都对内存中文档对象进行。

    2)SAX思想:一边解析,一边处理,一边释放内存资源---不允许在内存中保留大规模XML数据

    3)DOM和SAX的区别

    DOM:支持回写,会将整个XML载入内存,以树形结构方式存储

                XML比较复杂的时候,或者当你需要随机处理文档中数据的时候不建议使用

    SAX:相比DOM是一种更为轻量级的方案

              无法在读取过程中修改XML数据

    2.常用解析开发包:JAXP、DOM4J

    3.DOM解析原理图

    4.使用JAXP进行DOM解析

    JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成:

    org.w3c.dom:提供DOM方式解析XML的标准接口

    org.xml.sax:提供SAX方式解析XML的标准接口

    javax.xml:提供了解析XML文档的类

    5.JAXP进行DOM解析的实例(增删改查)

    book.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
        <书 ISBN="a11" 出版社="清华大学出版社">
            <书名>JavaSE基础</书名>
            <作者>张三</作者>
            <批发价>35.00元</批发价>
            <售价>38.00元</售价>
        </>
        <书 ISBN="b11" 出版社="北京大学出版社">
            <书名>Android</书名>
            <作者>李四</作者>
            <售价>38.00元</售价>
        </>
    </书架>

    JaxpDomDemo.java

    package cn.lsl.jaxp;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    public class JaxpDomDemo {
        public static void main(String[] args) throws Exception {
            //得到解析工厂DocumentBuilderFactory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //得到解析器DocumentBuilder
            DocumentBuilder builder =  factory.newDocumentBuilder();
            //解析指定的XML文档,得到代表内存DOM树的Document对象
            Document document = builder.parse("src/book.xml");
            test8(document);
        }
        //1.得到某个具体节点内容:打印第2本书的作者
        public static void test1(Document document){
            //根据标签的名称获取所有的作者元素
            NodeList nodeList = document.getElementsByTagName("作者");
            //按照索引取第2个作者元素
            Node node = nodeList.item(1);
            //打印该元素的文本
            String text = node.getTextContent();
            System.out.println(text);
        }
        
        // 2、遍历所有元素节点:打印元素的名称
        public static void test2(Node node){
            //判断当前节点是不是一个元素节点
            if(node.getNodeType() == Node.ELEMENT_NODE){
                //如果是:打印他的名称
                System.out.println(node.getNodeName());
            }
            //查找子节点
            NodeList nodeList = node.getChildNodes();
            int len = nodeList.getLength();
            for (int i = 0; i < len; i++) {
                Node n = nodeList.item(i);
                test2(n);
            }
        }
        
        
        //3、修改某个元素节点的主体内容:把第一本书的售价改为38.00元
        public static void test3(Document document) throws Exception{
            //找到第一本书的售价
            NodeList nodeList = document.getElementsByTagName("售价");
            //设置其主体内容
            Node node = nodeList.item(0);
            node.setTextContent("38.00元");
            //把内存中Document树写回xml文件中
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer ts = factory.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
        }
        
        //4.向指定元素节点中增加子元素节点:第一本中增加子元素<内部价>29.00</内部价>
        public static void test4(Document document) throws Exception{
            //创建一个新的元素并设置其主体内容
            Element e = document.createElement("内部价");
            e.setTextContent("29.00元");
            //找到第一本书元素
            Node firstBookNode = document.getElementsByTagName("书").item(0);
            //把新节点挂接到第一本书上
            firstBookNode.appendChild(e);
            //把内存中Document树写回XML文件中
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer ts = factory.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
        }
        
        //5.向指定元素节点上增加同级元素节点:在第一本书的售价前面增加批发价
        public static void test5(Document document) throws Exception{
            //创建一个新的元素并设置其中的主题内容
            Element e = document.createElement("批发价");
            e.setTextContent("35.00元");
            //找到第一本书的售价
            Node firstPrice = document.getElementsByTagName("售价").item(0);
            //在售价的前面加入新建的元素:增加子元素一定要用父元素来增加
            firstPrice.getParentNode().insertBefore(e, firstPrice);
            //把内存中Document树写回XML文件中
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer ts = factory.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
        }
        
        
        //6.删除指定元素节点:删除内部价
        public static void test6(Document document) throws Exception{
            //找到内部价节点,用父节点删除
            Node n = document.getElementsByTagName("内部价").item(0);
            n.getParentNode().removeChild(n);
            //把内存中Document书写回XML文件中
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer ts = factory.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
        }
        
        
        //7、操作XML文件属性:打印第一本书的出版社
        public static void test7(Document document){
            //得到第一本书
            Node n = document.getElementsByTagName("书").item(0);
            //打印指定属性的取值
            Element e = (Element)n;
            System.out.println(e.getAttribute("出版社"));
        }
        
        
        //8、添加一个出版社属性给第二本书
        public static void test8(Document document) throws Exception{
            //得到第二本书
            Node n = document.getElementsByTagName("书").item(1);
            //打印指定属性的取值
            Element e = (Element)n;
            e.setAttribute("出版社", "北京大学出版社");
            //把内存中Document树写回XML文件中
            TransformerFactory factory  = TransformerFactory.newInstance();
            Transformer ts = factory.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
        }    
    }

    6.案例(学生成绩的增删改查,采用分层开发)

    案例原型

    exam.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?><exam>
        <student examid="444" idcard="333">
            <name>李四</name>
            <location>大连</location>
            <grade>97</grade>
        </student>
        <student examid="666" idcard="555">
            <name>小舒</name>
            <location>福建</location>
            <grade>90.0</grade>
        </student>
    </exam>

    实体类:Student.java

    package cn.lsl.domain;
    
    public class Student {
        private String idcard;
        private String examid;
        private String name;
        private String location;
        private Double grade;
        public String getIdcard() {
            return idcard;
        }
        public void setIdcard(String idcard) {
            this.idcard = idcard;
        }
        public String getExamid() {
            return examid;
        }
        public void setExamid(String examid) {
            this.examid = examid;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getLocation() {
            return location;
        }
        public void setLocation(String location) {
            this.location = location;
        }
        public Double getGrade() {
            return grade;
        }
        public void setGrade(Double grade) {
            this.grade = grade;
        }
        @Override
        public String toString() {
            return "Student [examid=" + examid + ", grade=" + grade + ", idcard="
                    + idcard + ", location=" + location + ", name=" + name + "]";
        }
    }

    工具类:DocumentUtil.java

    package cn.lsl.util;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.w3c.dom.Document;
    //操作XML的工具类
    //工具类中的异常可以抛也可以处理
    public class DocumentUtil {
        public static Document getDocument() throws Exception{
            DocumentBuilder builder =  DocumentBuilderFactory.newInstance().newDocumentBuilder();
            return builder.parse("src/exam.xml");
        }
        
        public static void write2xml(Document document) throws Exception{
            Transformer ts = TransformerFactory.newInstance().newTransformer();
            ts.transform(new DOMSource(document), new StreamResult("src/exam.xml"));
        }
    }

    DAO层:(StudentDao.java)

    package cn.lsl.dao;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import cn.lsl.domain.Student;
    import cn.lsl.util.DocumentUtil;
    
    public class StudentDao {
        
        //添加学生信息到XML中
        public boolean createStudent(Student s){
            boolean result = false;
            try{
                Document document = DocumentUtil.getDocument();
                //创建name、location、grade元素并设置内容
                Element nameE = document.createElement("name");
                nameE.setTextContent(s.getName());
                Element locationE = document.createElement("location");
                locationE.setTextContent(s.getLocation());
                Element gradeE = document.createElement("grade");
                gradeE.setTextContent(s.getGrade()+"");
                //创建student元素,并设置属性
                Element studentE = document.createElement("student");
                studentE.setAttribute("idcard", s.getIdcard());
                studentE.setAttribute("examid", s.getExamid());
                
                studentE.appendChild(nameE);
                studentE.appendChild(locationE);
                studentE.appendChild(gradeE);
                //得到exam元素,把student挂接上去
                Node node = document.getElementsByTagName("exam").item(0);
                node.appendChild(studentE);
                //写回XML文件中
                DocumentUtil.write2xml(document);
                result = true;
            }catch(Exception e){
                throw new RuntimeException(e);    //异常转义。异常链
            }
            return result;
        }
        
        
        //根据准考证号查询学生信息
        public Student findStudent(String examid){
            Student s = null;
            try{
                Document document = DocumentUtil.getDocument();
                //得到所有student元素
                NodeList nodelist = document.getElementsByTagName("student");
                //遍历student元素,判断他的examid属性的取值是否与参数匹配
                for (int i = 0; i < nodelist.getLength(); i++) {
                    Node node = nodelist.item(i);
                    if(node instanceof Element){
                        Element e = (Element)node;
                        if(e.getAttribute("examid").equals(examid)){
                            //如果匹配,说明找到了学生,创建学生对象
                            s = new Student();
                            s.setExamid(examid);
                            s.setIdcard(e.getAttribute("idcard"));
                            s.setName(e.getElementsByTagName("name").item(0).getTextContent());
                            s.setLocation(e.getElementsByTagName("location").item(0).getTextContent());
                            s.setGrade(Double.parseDouble(e.getElementsByTagName("grade").item(0).getTextContent()));
                        }
                    }
                }
            }catch(Exception e){
                throw new RuntimeException(e);
            }
            return s;
        }
        
        
        //根据学生姓名删除学生
        public boolean deleteStudent(String name){
            boolean result = false;
            try{
                //得到Document对象
                Document document = DocumentUtil.getDocument();
                NodeList nodelist = document.getElementsByTagName("name");
                for(int i=0; i<nodelist.getLength(); i++){
                    Node node = nodelist.item(i);
                    if(node.getTextContent().equals(name)){
                        node.getParentNode().getParentNode().removeChild(node.getParentNode());
                        //写回XML文档
                        DocumentUtil.write2xml(document);
                        result = true;
                        break;
                    }
                }
            }catch(Exception e){
                    throw new RuntimeException(e);
            }
            return result;
        }
    }

    View层(Main.java)

    package cn.lsl.view;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    import cn.lsl.dao.StudentDao;
    import cn.lsl.domain.Student;
    
    public class Main {
        public static void main(String[] args) {
            try{
                StudentDao dao = new StudentDao();
                System.out.println("a、添加学生	b、删除学生	c、查询成绩");
                System.out.println("请输入操作类型");
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String operation = br.readLine();
                if("a".equals(operation)){
                    //添加操作
                    System.out.println("请输入学生姓名");
                    String name = br.readLine();
                    System.out.println("请输入学生准考证号");
                    String examid = br.readLine();
                    System.out.println("请输入学生身份证号");
                    String idcard = br.readLine();
                    System.out.println("请输入学生所在地");
                    String location = br.readLine();
                    System.out.println("请输入学生成绩");
                    String grade = br.readLine();
                    Student s = new Student();
                    s.setExamid(examid);
                    s.setIdcard(idcard);
                    s.setName(name);
                    s.setLocation(location);
                    s.setGrade(Double.parseDouble(grade));
                    //System.out.println(s);
                    boolean b = dao.createStudent(s);
                    if(b){
                        System.out.println("---添加成功---");
                    }else{
                        System.out.println("对不起!数据有误");
                    }
                }else if("b".equals(operation)){
                    System.out.println("请输入要删除的学生姓名:");
                    String name = br.readLine();
                    boolean b = dao.deleteStudent(name);
                    if(b){
                        System.out.println("--删除成功--");
                    }else{
                        System.out.println("对不起!删除失败或者学生不存在");
                    }
                }else if("c".equals(operation)){
                    //查询操作
                    System.out.println("请输入要查询的学生准考证号:");
                    String examid = br.readLine();
                    Student s = dao.findStudent(examid);
                    if(s == null){
                        System.out.println("对不起!您查询的学生不存在");
                    }else{
                        System.out.println(s);
                    }
                }else{
                    System.out.println("请输入正确的操作类型");
                }
            }catch(Exception e){
                System.out.println("对不起!服务器忙!");
            }
        }
    }

    7.SAX解析原理图

    8. SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器。

    9.SAX解析

    实例一:

    book.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <书架> 
      <书 出版社="清华大学出版社"> 
        <书名>JavaSE基础</书名>  
        <作者>张三</作者>  
        <售价>38.00</售价>  
        <内部价>19.00</内部价> 
      </>  
      <> 
        <书名>Android</书名>  
        <作者>李四</作者>  
        <售价>28.00</售价> 
      </> 
    </书架>

    SAXDemo1.java

    package cn.lsl.sax;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.ContentHandler;
    import org.xml.sax.Locator;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    
    //JAXP进行SAX解析
    public class SAXDemo1 {
        public static void main(String[] args) throws Exception {
            //得到解析工厂SAXParserFactory
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //得到解析器SAXParser
            SAXParser parser = factory.newSAXParser();
            //得到XML读取器:XMLReader
            XMLReader reader = parser.getXMLReader();
            //注册内容处理器:ContentHandler
            reader.setContentHandler(new MyContentHandler());
            //取出XML文档
            reader.parse("src/book.xml");
        }
    }
    
    class MyContentHandler implements ContentHandler{
        
        //解析到文档开始时被调用
        @Override
        public void startDocument() throws SAXException {
            System.out.println("解析到了文档的开始");
        }
        
        //解析到了元素开始时被调用:    qName元素名称
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes atts) throws SAXException {
            System.out.println("解析到了元素的开始:"+qName);
        }
    
        //解析到了文本内容被调用
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            System.out.println("文本内容:"+new String(ch,start,length));
        }
        
        
        //解析到元素结束时被调用
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            System.out.println("解析到了元素的结束:"+qName);
        }
        
        //解析到文档结束时被调用
        @Override
        public void endDocument() throws SAXException {
            System.out.println("解析到了文档的结束");
        }
        
        
    
        @Override
        public void endPrefixMapping(String prefix) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void ignorableWhitespace(char[] ch, int start, int length)
                throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void processingInstruction(String target, String data)
                throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void setDocumentLocator(Locator locator) {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void skippedEntity(String name) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void startPrefixMapping(String prefix, String uri)
                throws SAXException {
            // TODO Auto-generated method stub
            
        }
    }

    实例二:

    SAXDemo2.java

    package cn.lsl.sax;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.ContentHandler;
    import org.xml.sax.Locator;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    
    //打印第2本书的作者    
    public class SAXDemo2 {
        public static void main(String[] args) throws Exception {
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            XMLReader reader = parser.getXMLReader();
            reader.setContentHandler(new ContentHandler(){    //匿名内部类
                boolean isAuthor = false;    //是不是作者标签
                int index = 0;    //作者标签的索引
                
                @Override
                public void startElement(String uri, String localName,
                        String qName, Attributes atts) throws SAXException {
                    if("作者".equals(qName)){
                        isAuthor = true;
                    }
                }
                
                
                @Override
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                    if(isAuthor&&index==1){
                        System.out.println(new String(ch,start,length));
                    }
                }
                
                @Override
                public void endElement(String uri, String localName, String qName)
                        throws SAXException {
                    if("作者".equals(qName)){
                        index++;
                    }
                    isAuthor = false;
                }
    
                @Override
                public void endDocument() throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
                
    
                @Override
                public void endPrefixMapping(String prefix) throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
    
                @Override
                public void ignorableWhitespace(char[] ch, int start, int length)
                        throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
    
                @Override
                public void processingInstruction(String target, String data)
                        throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
    
                @Override
                public void setDocumentLocator(Locator locator) {
                    // TODO Auto-generated method stub
                    
                }
    
                @Override
                public void skippedEntity(String name) throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
    
                @Override
                public void startDocument() throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
    
                
    
                @Override
                public void startPrefixMapping(String prefix, String uri)
                        throws SAXException {
                    // TODO Auto-generated method stub
                    
                }
                
            });
            reader.parse("src/book.xml");
        }
    }

    实例三:读取XML内容,封装到JavaBean

    Book.java

    package cn.lsl.domain;
    
    public class Book {
        private String name;
        private String author;
        private Double price;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAuthor() {
            return author;
        }
        public void setAuthor(String author) {
            this.author = author;
        }
        public Double getPrice() {
            return price;
        }
        public void setPrice(Double price) {
            this.price = price;
        }
        @Override
        public String toString() {
            return "Book [author=" + author + ", name=" + name + ", price=" + price
                    + "]";
        }
    }

    SAXDemo3.java

    package cn.lsl.sax;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    import org.xml.sax.helpers.DefaultHandler;
    
    import cn.lsl.domain.Book;
    
    
    //读取XML内容,封装到JavaBean
    public class SAXDemo3 {
        public static void main(String[] args) throws Exception {
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            XMLReader reader =  parser.getXMLReader();
            final List books = new ArrayList();
            reader.setContentHandler(new DefaultHandler(){
                Book book = null;
                String currentTagName = null;
                @Override
                public void startElement(String uri, String localName,
                        String qName, Attributes attributes) throws SAXException {
                    if("书".equals(qName)){
                        book = new Book();
                    }
                    currentTagName = qName;
                }
                @Override
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                    if("书名".equals(currentTagName)){
                        book.setName(new String(ch,start,length));
                    }
                    if("作者".equals(currentTagName)){
                        book.setAuthor(new String(ch,start,length));
                    }
                    if("售价".equals(currentTagName)){
                        book.setPrice(Double.parseDouble(new String(ch,start,length)));
                    }
                }
                @Override
                public void endElement(String uri, String localName, String qName)
                        throws SAXException {
                    if("书".equals(qName)){
                        books.add(book);
                        book = null;
                    }
                    currentTagName = null;
                }
            });
            reader.parse("src/book.xml");
            for (Object b:books) {
                System.out.println(b);
            }
        }
    }
  • 相关阅读:
    Chevy equinox
    回家线路
    salesforce account hierarchy
    IOS8 对flex兼容性问题
    Chrome FeHelper 插件下载地址
    vue 项目抛出警告
    vue 干货
    Error in mounted hook: "TypeError: handlers[i].call is not a function" 原因
    vue 路由知识点(一级路由与二级路由嵌套)
    (转)ORA-01940: cannot drop a user that is currently connected 问题解析
  • 原文地址:https://www.cnblogs.com/EvanLiu/p/3665113.html
Copyright © 2011-2022 走看看