zoukankan      html  css  js  c++  java
  • JavaEE:XML解析

    XML解析技术概述
    1.XML 技术主要企业应用
    1)存储和传输数据
    2)作为框架的配置文件
    2.使用xml 存储和传输数据涉及到以下两点
    1)通过程序生成xml
    2)读取xml 中数据 ---- xml 解析
    3.XML解析技术有三种:DOM、SAX、STAX
    4.什么是DOM和SAX ?
    1)DOM  Document Object Model ----- 文档对象模型
    DOM思想:将整个xml 加载内存中,形成文档对象,所有对xml操作都对内存中文档对象进行
    DOM 是官方xml解析标准
    * DOM是所有所有开发语言都支持的
    2)SAX  Simple API for XML ----- XML 简单 API
    为什么发明sax解析方式?  当xml 文档非常大,不可能将xml所有数据加载到内存
    SAX 思想:一边解析 ,一边处理,一边释放内存资源 ---- 不允许在内存中保留大规模xml 数据
    3)StAX The Stream API for XML ----- XML 流 API
    JDK6的新特性STAX是JDK6.0中除了DOM和SAX之外的又一种拉模式处理XML文档的API,其思想和SAX相似
    STAX 是一种 拉模式 xml 解析方式,SAX 是一种 推模式 XML 解析方式
    推push模式:由服务器为主导,向客户端主动发送数据
    拉pull模式: 由客户端为主导,主动向服务器申请数据
    5.XML解析开发包
    Jaxp(sun)、xml pull 、dom4j
    JAXP 是sun官方推出实现技术 同时支持 DOM SAX STAX
    DOM4j 是开源社区开源框架  支持 DOM 解析方式
    XML PULL是Android 移动设备内置xml 解析技术 支持 STAX 解析方式
    6.解析方式与解析开发包关系?
    解析方式是解析xml 思想,没有具体代码,解析开发包是解析xml思想具体代码实现
    7.DOM和SAX/STAX的区别
    DOM  
    支持回写
    会将整个XML载入内存,以树形结构方式存储
    XML比较复杂的时候,或者当你需要随机处理文档中数据的时候不建议使用
    SAX / STAX
    相比DOM是一种更为轻量级的方案
    采用串行方法读取 --- 文件输入流(字节、字符)读取
    编程较为复杂
    无法在读取过程中修改XML数据

    注意:当SAX和STAX 读取xml数据时,如果读取到内存数据不释放 ----- 内存中将存在整个xml文档数据 (类似DOM 支持修改和回写)

    8.DOM、SAX、STAX 在实际开发中选择?
    在javaee日常开发中 ---- 优先使用DOM (编程简单)
    当xml 文档数据非常多,不可能使用DOM ---造成内存溢出  ------ 优先使用STAX
    移动开发 使用 STAX ---- Android XML PULL

    DOM解析

    DOM解析结构图

    1.DOM 解析快速入门
    1)创建 xml 文档 books.xml
    在企业实际开发中,为了简化xml 生成和解析 ---- xml 数据文件通常不使用约束的
    2)使用DOM解析xml
    将整个xml文档加载到内存中 : 工厂 --- 解析器 --- 解析加载
    3)Document通过getElementsByTagName获得节点集合NodeList
    通过NodeList提供getLength和item遍历节点集合

    遍历ArrayList

    for (int i=0;i<arraylist.size();i++){
       arraylist.get(i);
    }

    遍历NodeList

    for (int i=0;i<nodelist.getLength();i++){
      nodelist.item(i);  ----- 将遍历每个节点转换子接口类型
    }


    什么是 Node? 对于xml 来说,xml所有数据都是node节点 (元素节点、属性节点、文本节点、注释节点、CDATA节点、文档节点)
    Element Attr Text Comment CDATASection Document  ----- 都是 Node 子接口

    node有三个通用API :
    getNodeName():返回节点的名称
    getNodeType():返回节点的类型
    getNodeValue():返回节点的值  ---- 所有元素节点value都是 null

    2.DOM 编程思路小结
    1)装载XML文档 ---- Document
    2)Document 获得指定元素 ----- getElementsByTagName (返回 NodeList)
    3)遍历NodeList 获得 每个 Node
    4)将每个Node 强制转换 Element
    5)通过元素节点API 操作属性和文本内容
    getAttribute  获得属性值
    getTextContent 获得元素内部文本内容

    eg:

    <?xml version="1.0" encoding="UTF-8"?>
    <books>
        <book>
            <name>java编程思想</name>
            <price>80</price>
        </book>
        <book>
            <name>javaEE</name>
            <price>100</price>
        </book>
    </books>
    package cn.lsl.dom.jaxp;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    public class DOMTest {
        
        @Test
        public void demo1() throws Exception{
            //构造工厂
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            //通过工厂获得解析器
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            //使用解析器加载xml文档
            //Document代表整个xml文档,通过操作Document,操作xml数据
            Document document = builder.parse("books.xml");
            //nodelist代表节点集合
            NodeList nodelist = document.getElementsByTagName("name");
            System.out.println("图书name节点数量:" + nodelist.getLength());
            //便利集合中所有node
            for(int i=0; i<nodelist.getLength(); i++){
                //获得每个node
                Node node = nodelist.item(i);
                Element e = (Element)node;        //将节点转换为子类型节点
                System.out.println(e.getNodeName());
                System.out.println(e.getNodeType());
                System.out.println(e.getNodeValue());
                System.out.println(e.getFirstChild().getNodeValue());
                System.out.println(e.getTextContent());
                System.out.println("=========");
            }
        }
    }

    DOM的增删改查
    查询:
    eg:

    package cn.lsl.dom.jaxp;
    import java.io.File;
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
        
    public class DOMTest {
            
        //方法二:
        @Test
        public void demo3() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            NodeList nodelist = document.getElementsByTagName("name");
            for(int i=0; i<nodelist.getLength(); i++){
                Element name = (Element)nodelist.item(i);
                if(name.getTextContent().equals("java编程思想")){
                    Element price = (Element)name.getNextSibling().getNextSibling();
                    System.out.println(price.getTextContent());
                }
            }
        }
        
        //方法一
        //查询java编程思想 的售价
        @Test
        public void demo2() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            
            //全局查询,作为程序的切入
            NodeList nodelist = document.getElementsByTagName("book");
            //遍历,强制转换Element
            for(int i=0; i<nodelist.getLength(); i++){
                Element book = (Element)nodelist.item(i);
                //找出哪个book节点当中name节点值为java编程基础  --- 查找book的name子节点
                NodeList children = book.getChildNodes();
                Element name = (Element)children.item(1);
                if(name.getTextContent().equals("java编程思想")){
                    Element price = (Element)children.item(3);
                    System.out.println(price.getTextContent());
                }
            }
        }
    }

    getElementById方法,必须用于带有约束xml文档中!!!
    根据ID查询

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE books[
        <!ELEMENT books (book+)>
        <!ELEMENT book (name, price)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT price (#PCDATA)>
        <!ATTLIST book
            id ID #REQUIRED
        >
    ]>
    <books>
        <book id="b001">
            <name>java编程思想</name>
            <price>80</price>
        </book>
        <book id="b002">
            <name>javaEE</name>
            <price>100</price>
        </book>
    </books>
    package cn.lsl.dom.jaxp;
    import java.io.File;
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
        
    public class DOMTest {
            
        @Test
        public void demo4() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            
            Element book = document.getElementById("b002");
            System.out.println(book);
            System.out.println(book.getChildNodes().item(1).getTextContent());
        }
    }

    回写

    package cn.lsl.dom.jaxp;
    
    import java.io.File;
    
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
        
    public class DOMTest {
        
        //将 books.xml 加载内存中,将文档内容 写入另一个xml books_bak.xml    
        @Test
        public void demo5() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            //回写xml,用到Transformer
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
                
            DOMSource domSource = new DOMSource(document);    //用document构造数据源
            StreamResult result = new StreamResult(new File("book_bak.xml"));
            transformer.transform(domSource, result);
        }
    }

    XML元素添加:1.创建节点元素;2.将节点元素加入指定位置

    package cn.lsl.dom.jaxp;
    
    import java.io.File;
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    
    public class DOMCURDTest {
        @Test
        public void testAdd() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            
            //添加节点,创建节点books
            Element newBook = document.createElement("book");
            newBook.setAttribute("id", "b003");
            
            //创建name节点
            Element newName = document.createElement("name");
            newName.setTextContent("编程高手");
            //将新name放入新book
            newBook.appendChild(newName);
            //添加节点到指定位置 ---- 获得books根节点
            Element root = document.getDocumentElement();
            root.appendChild(newBook);
            
            //回写
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource domSource = new DOMSource(document);
            StreamResult result = new StreamResult(new File("book_bak.xml"));
            transformer.transform(domSource, result);
        }
    }

    XML元素修改:查询到指定元素 1、修改属性 setAttribute  2、修改元素文本内容 setTextContent

    package cn.lsl.dom.jaxp;
    import java.io.File;
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;
    
    public class DOMCURDTest {
        
        @Test
        public void testUpdate() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            NodeList nodelist = document.getElementsByTagName("name");
            for(int i=0; i<nodelist.getLength(); i++){
                Element name = (Element)nodelist.item(i);
                if(name.getTextContent().equals("javaEE")){
                    Element price = (Element)name.getNextSibling().getNextSibling();
                    double money = Double.parseDouble(price.getTextContent());
                    money = money * 1.2;
                    price.setTextContent(money + "");
                }
            }
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource domSource = new DOMSource(document);
            StreamResult result = new StreamResult(new File("book_bak.xml"));
            transformer.transform(domSource, result);
        }
    }

    XML元素删除: 删除节点.getParentNode().removeChild(删除节点)

    package cn.lsl.dom.jaxp;
    
    import java.io.File;
    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.junit.Test;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;
    
    public class DOMCURDTest {
        
        @Test
        public void testDelete() throws Exception{
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse("books.xml");
            NodeList nodelist = document.getElementsByTagName("name");
            for(int i=0; i<nodelist.getLength(); i++){
                Element name = (Element)nodelist.item(i);
                if(name.getTextContent().contains("java")){
                    Element book = (Element)name.getParentNode();
                    book.getParentNode().removeChild(book);
                    i--;
                }
            }
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource domSource = new DOMSource(document);
            StreamResult result = new StreamResult(new File("book_bak.xml"));
            transformer.transform(domSource, result);
        }
    }

    SAX解析

    sax解析原理图


    1.SAX和STAX都是基于时间驱动  --- SAX是推模式 STAX是拉模式
    2.SAX常用事件
    startDocument() --- 文档开始事件
    startElement() --- 元素开始事件
    characters() --- 文本元素事件
    endElement() --- 元素结束事件
    endDocument() --- 文档结束事件
    3.为什么说SAX是推模式?
    解析器控制xml文件解析,由解析器调用相应事件方法

    在startElement() endElement()获得开始和结束元素名称
    在characters()获得读取到文本内容

    eg:

    <?xml version="1.0" encoding="UTF-8"?>
    <config>
        <server id="s100">UNIX</server>
    </config>
    package cn.lsl.jaxp.sax;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    public class SAXTest {
        public static void main(String[] args) throws Exception, Exception {
            //1.工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //2.通过工厂获得解析器
            SAXParser parser = factory.newSAXParser();
            //3.创建Handler
            MyHandler handler = new MyHandler();
            parser.parse("server.xml", handler);
        }
    }
    
    
    class MyHandler extends DefaultHandler{
        @Override
        public void startDocument() throws SAXException {
            System.out.println("start document...");
        }
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            System.out.println("start elemnt("+qName+")...");
            if(qName.equals("server")){
                System.out.println("id属性值:" + attributes.getValue("id"));
            }
        }
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String content = new String(ch, start, length);
            System.out.println("character:" + content);
        }
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            System.out.println("end element("+ qName +")...");
        }
        @Override
        public void endDocument() throws SAXException {
            System.out.println("end document...");
        }
    }

    STAX解析
    1.STAX是拉模式的xml解析方式
    (为什么是拉模式?)客户端程序,自己控制xml事件,主动调用相应事件方法
    2.当使用XML PULL,如果使用Android系统,系统内置无需下载任何开发包,如果想JavaSE JavaEE使用pull解析技术,下载单独pull开发工具包
    3.xpp3 --- XML Pull Parser 3 是pull API代码实现
    4.使用pull解析器
    1)下载pull解析器xpp3(Android内置)
    2)将 xpp3-1.1.3.4.C.jar 导入 java工程
    3)导入jar包 位于 当前工程内部 , 在工程内新建 lib ,将jar复制过来 , 将pull 解析器 jar 添加build path
    5.Pull解析器使用STAX解析方式 --- 拉模式解析
    6.Pull采用将xml文档传递解析器,手动通过next触发文档解析事件,在客户端代码中获取当前事件,从而调用相应事件处理方法
    7.为什么STAX解析方式效率好于SAX?
    1)SAX无选择性的,所有事件都会处理的解析方式,STAX由用户控制需要处理事件类型
    2)在使用STAX进行数据解析时,随时终止解析

    Pull解析原理


    8.Pull解析的快速入门案例

    <?xml version="1.0" encoding="UTF-8"?>
    <books>
        <book id="b001">
            <name>java编程基础</name>
            <price>80</price>
        </book>
        <book id="b002">
            <name>java高级应用</name>
            <price>100</price>
        </book>
        <book id="boo3">
            <name>编程高手秘笈</name>
            <price>200</price>
        </book>    
    </books>
    package cn.lsl.pull.stax;
    import java.io.FileInputStream;
    import org.junit.Test;
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserFactory;
    
    public class PullTest {
        
        //查询 编程高手秘笈的价格
        @Test
        public void demo2() throws Exception{
            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = xmlPullParserFactory.newPullParser();
            parser.setInput(new FileInputStream("books.xml"),"utf-8");
            
            int event;
            //定义标志位
            boolean isFound = false;
            while((event = parser.getEventType())!= XmlPullParser.END_DOCUMENT){
                if(event == XmlPullParser.START_TAG && parser.getName().equals("name")){
                    String bookname = parser.nextText();
                    if(bookname.equals("编程高手秘笈")){
                        isFound = true;
                    }
                }
                
                if(event == XmlPullParser.START_TAG && parser.getName().equals("price") && isFound){
                    System.out.println(parser.nextText());
                    break;
                }
                
                parser.next();
            }
        }
        
        @Test
        public void demo1() throws Exception{
            //1.工厂
            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
            //2.通过工厂获得解析器
            XmlPullParser parser = xmlPullParserFactory.newPullParser();
            //3.将xml文件传递给解析器
            parser.setInput(new FileInputStream("books.xml"), "utf-8");
            
            //pull解析器用拉模式解析数据
            int event;
            while((event = parser.getEventType()) != XmlPullParser.END_DOCUMENT){
                if(event == XmlPullParser.START_TAG){
                    System.out.println(parser.getName() + "元素开始了...");
                }
                if(event == XmlPullParser.END_TAG){
                    System.out.println(parser.getName() + "元素结束了...");
                }
                parser.next();
            }
        }
    }

    9.Pull解析器生成xml文档功能 --- 通过XmlSerializer生成xml文档
    解析xml:文档开始、元素开始、文本元素、元素结束、文档结束
    生成xml:生成文档声明(文档开始)、元素开始、文本内容、元素结束、文档结束
    三种方式生成xml
    1)生成简单xml
    2)通过对象数据生成xml
    3)通过对象List数据生成xml

    eg:

    package cn.lsl.domain;
    
    public class Company {
        private String name;
        private int num;
        private String address;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getNum() {
            return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
    }
    package cn.lsl.pull.stax;
    
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Test;
    import org.xmlpull.v1.XmlPullParserException;
    import org.xmlpull.v1.XmlPullParserFactory;
    import org.xmlpull.v1.XmlSerializer;
    
    import cn.lsl.domain.Company;
    
    public class SerializerTest {
        
        
        //根据List<Company>生成xml
        @Test
        public void demo3() throws Exception{
            List<Company> companies = new ArrayList<Company>();
            Company company = new Company();
            company.setName("软件公司");
            company.setNum(200);
            company.setAddress("软件园");
            
            Company company2 = new Company();
            company2.setName("科技公司");
            company2.setNum(1000);
            company2.setAddress("软件园");
            
            companies.add(company);
            companies.add(company2);
            
            XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
            serializer.setOutput(new FileOutputStream("company.xml"), "utf-8");
            serializer.startDocument("utf-8", true);
            serializer.startTag(null, "companies");
            for(Company c : companies){
                serializer.startTag(null, "company");
                
                serializer.startTag(null, "name");
                serializer.text(c.getName());
                serializer.endTag(null, "name");
                
                serializer.startTag(null, "num");
                serializer.text(c.getNum()+"");
                serializer.endTag(null, "num");
                
                serializer.startTag(null, "address");
                serializer.text(c.getAddress());
                serializer.endTag(null, "address");
                
                serializer.endTag(null, "company");
            }
            serializer.endTag(null, "companies");
            serializer.endDocument();
        }
        
        //根据company对象数据生成xml
        @Test
        public void demo2() throws Exception{
            Company company = new Company();
            company.setName("软件公司");
            company.setNum(200);
            company.setAddress("软件园");
            XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
            serializer.setOutput(new FileOutputStream("company.xml"), "utf-8");
            serializer.startDocument("utf-8", true);
            serializer.startTag(null, "company");
            
            serializer.startTag(null, "name");
            serializer.text(company.getName());
            serializer.endTag(null, "name");
            
            serializer.startTag(null, "num");
            serializer.text(company.getNum()+"");
            serializer.endTag(null, "num");
            
            serializer.startTag(null, "address");
            serializer.text(company.getAddress());
            serializer.endTag(null, "address");
            
            serializer.endTag(null, "company");
            serializer.endDocument();
            
        }
        
        //生成xml
        @Test
        public void demo1() throws Exception{
            //获得XmlSerializer对象
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlSerializer serializer = factory.newSerializer();
            //设置序列化输出文档
            serializer.setOutput(new FileOutputStream("company.xml"), "utf-8");
            //文档开始
            serializer.startDocument("utf-8", true);
            //元素开始
            serializer.startTag(null, "company");
            //文本元素
            serializer.text("传智播客");
            //元素结束
            serializer.endTag(null, "company");
            //文档结束
            serializer.endDocument();
        }
    }

    10.Pull的CURD

    对XML数据通过Pull解析器进行CURD原理图


    先抽取工具类  两个方法 1.xml -- List  2.List --- xml

    package cn.lsl.pull.stax;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserFactory;
    import org.xmlpull.v1.XmlSerializer;
    
    import cn.lsl.domain.Company;
    
    //工具类 抽取两个方法:1、xml -- List 2、List --- XML
    public class PullUtils {
        //接收xml文件,返回List集合
        public static List<Company> parserXml2List(String fileName) throws Exception{
            List<Company> companies = new ArrayList<Company>();
            //获得解析器
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = factory.newPullParser();
            //设置xml输入文件
            parser.setInput(new FileInputStream(fileName), "utf-8");
            //遍历解析
            int event;
            Company company = null;
            while((event = parser.getEventType())!=XmlPullParser.END_DOCUMENT){
                //将每个<company>元素封装Company
                //1.在company开始时候,创建对象
                if(event == XmlPullParser.START_TAG && parser.getName().equals("company")){
                    company = new Company();
                }
                //2.读取name元素时,向company对象中封装name属性
                if(event == XmlPullParser.START_TAG && parser.getName().equals("name")){
                    company.setName(parser.nextText());
                }
                //3.读取num元素时,想company对象保存num属性
                if(event == XmlPullParser.START_TAG && parser.getName().equals("num")){
                    company.setNum(Integer.parseInt(parser.nextText()));
                }
                //4.读取address元素,向company封装address属性
                if(event == XmlPullParser.START_TAG && parser.getName().equals("address")){
                    company.setAddress(parser.nextText());
                }
                //5.读取company元素结束时,将company对象加入集合
                if(event == XmlPullParser.END_TAG && parser.getName().equals("company")){
                    companies.add(company);
                }
                parser.next();
            }
            return companies;
        }
        
        //同时接收xml文件和List集合,将集合中数据写入xml文件
        public static void serializeList2Xml(List<Company> companies, String fileName) throws Exception{
            //获取序列化对象
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlSerializer serializer = factory.newSerializer();
            //写文件之前,指定输出文件
            serializer.setOutput(new FileOutputStream(fileName), "utf-8");
            //文档开始
            serializer.startDocument("utf-8", true);
            //根元素开始companies
            serializer.startTag(null, "companies");
            //遍历集合List,每个List中Company对象生成一个片段
            for(Company company : companies){
                //company开始
                serializer.startTag(null, "company");
                //name属性开始
                serializer.startTag(null, "name");
                //写入name数据
                serializer.text(company.getName());
                //name属性结束
                serializer.endTag(null, "name");
                //num属性开始
                serializer.startTag(null, "num");
                //num写入num数据
                serializer.text(company.getNum() + "");
                //num属性结束
                serializer.endTag(null, "num");
                //address属性开始
                serializer.startTag(null, "address");
                //写入address值
                serializer.text(company.getAddress());
                //address属性结束
                serializer.endTag(null, "address");
                //company结束
                serializer.endTag(null, "company");
                
            }
            //根元素结束
            serializer.endTag(null, "companies");
            //文档结束
            serializer.endDocument();
        }
    }
    package cn.lsl.pull.stax;
    
    import java.io.FileInputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Test;
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserFactory;
    
    import cn.lsl.domain.Company;
    
    public class PullCURD {
        
        @Test
        //将科技公司从列表删除
        public void testDelete() throws Exception{
            //1.解析xml数据到内存list
            List<Company> companies = PullUtils.parserXml2List("company.xml");
            //2.从list集合中删除科技公司的company对象
            
            for(Company company : companies){
                if(company.getName().equals("科技公司")){
                    companies.remove(company);
                    break;
                    //如果没有加break;会发生并发访问异常,,因为foreach循环中不能改变长度,
                    //改变长度时在下一次判断长度会报异常,
                    //用break跳出循环,没有下一次判断长度,所以可以避免
                }
            }
            PullUtils.serializeList2Xml(companies, "company_bak.xml");
        }
        
        @Test
        //将科技公司人数增加200%
        public void testUpdate() throws Exception{
            //1.解析xml数据到内存list
            List<Company> companies = PullUtils.parserXml2List("company.xml");
            //2.增加科技公司人数200%
            for(Company company : companies){
                if(company.getName().equals("科技公司")){
                    company.setNum(company.getNum() * 2);
                }
            }
            PullUtils.serializeList2Xml(companies, "company_bak.xml");
        }
        
        @Test
        //查询软件公司的人数
        public void testSelect() throws Exception{
            //1.解析xml数据到内存list
            List<Company> companies = PullUtils.parserXml2List("company.xml");
            //2.遍历集合对象
            for(Company company : companies){
                if(company.getName().equals("软件公司")){
                    System.out.println(company.getNum());
                }
            }
        }
        
        @Test
        //向company出入一个公司
        public void testAdd() throws Exception{
            //1.解析xml数据到内存list
            List<Company> companies = PullUtils.parserXml2List("company.xml");
            //2.添加company对象
            Company company = new Company();
            company.setName("软件科技公司");
            company.setNum(5000);
            company.setAddress("软件园");
            companies.add(company);
            PullUtils.serializeList2Xml(companies, "company_bak.xml");
        }
        
        //测试工具类PullUtils中方法
        @Test
        public void demo2() throws Exception{
            //将company.xml复制company_bak.xml
            //解析获得集合
            List<Company> companies = PullUtils.parserXml2List("company.xml");
            //将集合写入company_bak.xml
            PullUtils.serializeList2Xml(companies, "company_bak.xml");
        }
        
        //将xml中数据 ---- List集合对象
        @Test
        public void demo1() throws Exception{
            List<Company> companies = new ArrayList<Company>();
            Company company = null;
            //获得解析器
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = factory.newPullParser();
            //向解析器传入xml文档
            parser.setInput(new FileInputStream("company.xml"), "utf-8");
            //遍历解析
            int event;
            while((event = parser.getEventType())!=XmlPullParser.END_DOCUMENT){
                if(event == XmlPullParser.START_TAG && parser.getName().equals("company")){
                    company = new Company();
                }
                if(event == XmlPullParser.START_TAG && parser.getName().equals("name")){
                    company.setName(parser.nextText());
                }
                if(event == XmlPullParser.START_TAG && parser.getName().equals("num")){
                    company.setNum(Integer.parseInt(parser.nextText()));
                }
                if(event == XmlPullParser.START_TAG && parser.getName().equals("address")){
                    company.setAddress(parser.nextText());
                }
                if(event == XmlPullParser.END_TAG && parser.getName().equals("company")){
                    companies.add(company);
                }
                parser.next();
            }
            
            for(Company c : companies){
                System.out.println(c.getName());
                System.out.println(c.getNum());
                System.out.println(c.getAddress());
                System.out.println("=========");
            }
        }
    }
  • 相关阅读:
    [CodeForces]Codeforces Round #429 (Div. 2) ABC(待补)
    About Me
    2018-06-14
    Codeforces Codeforces Round #484 (Div. 2) E. Billiard
    Codeforces Codeforces Round #484 (Div. 2) D. Shark
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
    Codeforces Avito Code Challenge 2018 D. Bookshelves
    Codeforces Round #485 (Div. 2) D. Fair
    Codeforces Round #485 (Div. 2) F. AND Graph
  • 原文地址:https://www.cnblogs.com/EvanLiu/p/3309054.html
Copyright © 2011-2022 走看看