基于SAX方式的解析、生成XML文档(适合收藏哦!!!)

今天我们来聊聊SAX方式解析、生成XML文档

SAX介绍:

1、SAX方式解析XML

1、具体流程

2、实现思路

3、要解析的acc.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
	<accounts>
		<account age="25" bankNo="acc1003">
			<id>610105200210102233</id>
			<name>小王</name>
			<money>6000.0</money>
		</account>
	</accounts>
复制代码

4、与xml的实体类Account.java

package com.yueqian.xml;
/**
 * 封装xml的实体类
 * @author LinChi
 *
 */
public class Account {
	private String bankNo;
	private int age;
	private String id;
	private String name;
	private double money;
	public Account() {
		super();
	}
	
	public Account(String bankNo, int age, String id, String name, double money) {
		super();
		this.bankNo = bankNo;
		this.age = age;
		this.id = id;
		this.name = name;
		this.money = money;
	}

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	
	public String getBankNo() {
		return bankNo;
	}
	public void setBankNo(String bankNo) {
		this.bankNo = bankNo;
	}
	@Override
	public String toString() {
		return this.bankNo+"|"+this.age+"|"+this.id+"|"+this.name+"|"+this.money;
	}
}
复制代码

5、定义事件监听器

package com.yueqian.xml2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.yueqian.xml.Account;
/**
 * 事件监听器
 * @author LinChi
 *
 */
public class AccountHandler extends DefaultHandler {
	//存放结果
	private List<Account> list = new ArrayList<Account>();
	//存放正在解析的Account对象
	private Account acc = null;
	//存放正在解析的子标签名称
	private String tagName = "";
	//创建线程池处理多个线程入库
	private ExecutorService exexutorPool = Executors.newFixedThreadPool(20);
	/**
	 * 开始处理标签
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		//当一个Account标签开始
		if("account".equals(qName)) {
			//创建对象
			acc = new Account();
			//获取属性
			Map<String,Object> map = getAttrsInfo(attributes);
			int age = 0;
			try {
				age = Integer.parseInt(map.get("age").toString());
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			acc.setAge(age);
			String bankNo = null;
			if(map.get("bankNo") != null) {
			bankNo = map.get("bankNo").toString();
			}
			acc.setBankNo(bankNo);
		}
		//记录处理标签的名称
		this.tagName = qName;
	}
	/**
	 * 结束标签
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		//判断结束标签是否为account
		if("account".equals(qName) && qName != null) {
			//将对象添加到集合中
			this.list.add(acc);
			//判断list数据是否到达100万行数据,如果到达,处理入库,入库成功后,清空list
			//转移数据时使用同步代码块保证多个线程执行数据的一致性
			if(this.list.size() >= 1000000) {
				List<Account> dbList = null;
				synchronized (list) {
					dbList = new ArrayList<Account>();
					dbList.addAll(list);
					list.clear();					
				}
				//让dbList多线程去入库,处理高并发大数据入库使用多线程去执行
//				new Thread(()->{
//					//入库dbList
//				}).start();
				//使用线程池让多个线程入库
				exexutorPool.execute(()->{
					//入库dbList
				});
			}
		}
		//清空标签的名称
		this.tagName = "";
	}
	/**
	 * 内容处理
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		if(this.acc == null) {
			return;
		}
		//获取id属性标签
		if("id".equals(this.tagName)) {
			String id = String.valueOf(ch,start,length);
			acc.setId(id);
		}
		//获取id属性标签
		if("name".equals(this.tagName)) {
			String name = String.valueOf(ch,start,length);
			acc.setName(name);
		}
		//获取id属性标签
		if("money".equals(this.tagName)) {
			String moneyStr = String.valueOf(ch,start,length);
			double money = 0;
			try {
				money = Double.parseDouble(moneyStr);
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			acc.setMoney(money);
		}
	}
	/**
	 * 获取属性信息
	 * @param attributes
	 * @param sb
	 */
	private Map<String,Object> getAttrsInfo(Attributes attributes) {
		Map<String,Object> attrMap = new HashMap<String,Object>();
		//过滤非法
		if(attributes == null || attributes.getLength() == 0) {
			return attrMap;
		}
		//循环获取属性
		for(int i = 0;i<attributes.getLength();i++) {
			String key = attributes.getQName(i);
			String var = attributes.getValue(i);
			attrMap.put(key, var);
		}
		return attrMap;
	}
	public List<Account> getList() {
		return list;
	}
	public void setList(List<Account> list) {
		this.list = list;
	}
}
复制代码

6、创建解析器

package com.yueqian.xml2;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import com.yueqian.xml.Account;



/**
 * sax解析器
 * @author LinChi
 *
 */
public class TestSax {
	public static void main(String[] args) {
		//定义解析器工厂类对象,通过该工厂对象获取解析器
		SAXParser parser;
		try {
			parser = SAXParserFactory.newInstance().newSAXParser();
			//解析文件
//			parser.parse(new File("I:/accs.xml"),new AccHandler());
			//创建事件驱动对象
			AccountHandler accHandler = new AccountHandler();
			parser.parse(new File("I:/accs.xml"),accHandler);
			List<Account> accList = accHandler.getList();
			System.out.println(accList);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
复制代码

7、项目成果截图

2、SAX生成XML

1、实现思路

2、代码实现

package com.yueqian.xml2;

import java.io.File;

import javax.swing.TransferHandler;
import javax.xml.crypto.dsig.Transform;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;

/**
 * Sax方式生成xml
 * @author LinChi
 *
 */
public class WriterSax {
	public static void main(String[] args) throws Exception {
		//创建保存xml的结果流对象
		Result resultXml = new StreamResult(new File("I:/computer.xml"));
		//获取Sax生成工厂实例
		SAXTransformerFactory stf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
		//获取SAX生成处理者对象实例
		TransformerHandler transformerHandler = stf.newTransformerHandler();
		//设置对象输入流
		transformerHandler.setResult(resultXml);
		//获取SAX生成器
		Transformer transformer = transformerHandler.getTransformer();
		//设置SAX生成文档  OutputKeys.INDENT表示文档可以有空格
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		
		//生成文档的开始
		transformerHandler.startDocument();
		//创建属性对象
		AttributesImpl attrImpl = new AttributesImpl();
		//添加属性
//		attrImpl.addAttribute(uri, localName, qName, type, value);
		//设置标签元素
		transformerHandler.startElement("","","书籍列表",attrImpl);
		transformerHandler.startElement("","","计算机书籍",attrImpl);
		transformerHandler.startElement("","","书名",attrImpl);
		//设置文本内容
		transformerHandler.characters("java思想".toCharArray(), 0, "java思想".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "书名");
		
		transformerHandler.startElement("","","作者",attrImpl);
		//设置文本内容
		transformerHandler.characters("小王".toCharArray(), 0, "小王".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "作者");
		
		transformerHandler.startElement("","","价格",attrImpl);
		//设置文本内容
		transformerHandler.characters("79.00".toCharArray(), 0, "79.00".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "价格");
		//设置结尾标签
		transformerHandler.endElement("","","计算机书籍");
		
		//第二本书
		transformerHandler.startElement("","","计算机书籍",attrImpl);
		transformerHandler.startElement("","","书名",attrImpl);
		//设置文本内容
		transformerHandler.characters("Spring指南".toCharArray(), 0, "Spring指南".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "书名");
		
		transformerHandler.startElement("","","作者",attrImpl);
		//设置文本内容
		transformerHandler.characters("小李".toCharArray(), 0, "小李".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "作者");
		
		transformerHandler.startElement("","","价格",attrImpl);
		//设置文本内容
		transformerHandler.characters("89.00".toCharArray(), 0, "89.00".length());
		//设置结尾标签
		transformerHandler.endElement("", "", "价格");
		//设置结尾标签
		transformerHandler.endElement("","","计算机书籍");
		transformerHandler.endElement("","","书籍列表");
		//告诉Handle文档生成已经结束
		transformerHandler.endDocument();
		System.out.println("XML生成成功!");
	}
}
复制代码

3、成果截图

今天的内容就分享到这了,期待明天的精彩分享吧!

猜你喜欢

转载自juejin.im/post/5e661acdf265da576f531753