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

 

 

 

转载于:https://www.cnblogs.com/EvanLiu/p/3309054.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值