• 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("=========");
            }
        }
    }
  • 相关阅读:
    Windows Subversion与TortoiseSVN安装与使用
    IE6/IE7中JavaScript json最后一个键值后不能增加逗号
    PHP json_encode/json_decode与serialize/unserializ性能测试
    Asp.Net中GridView加入鼠标滑过的高亮效果和单击行颜色改变
    创建sqlserver数据库脚本 范例
    搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 (二)创建你的项目
    搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 (三)实现数据库接口层和业务逻辑层
    创建SqlServer数据库触发器脚本 范例
    vss2005管理vs2010项目
    搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 (一)搭建你的环境
  • 原文地址:https://www.cnblogs.com/EvanLiu/p/3309054.html
Copyright © 2020-2023  润新知