SAX解析XML教程
加载XML文档文件
- 首先导入相关套件
import org.xml.sax.*;
- 在JAXP中,DOM解析器称为DocumentBulider,可以通过工厂类DocumentBuliderFactory获得,而document对象则可以通过类DocumentBulider获得。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.parse(file); // file为xml文件
} catch (ParserConfigurationException | SAXException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3.获取接口类document实例后,就可以对DOM的文档树进行访问。如要遍历DOM文档,首先获取根节点,然后获得根结点的子结点列表
// 获取根结点
Element root= document.getDocumentElement();
// 获取根结点点子结点列表
NodeList rootlist = document.getChildNodes();
设定加载XML文件的参数
|方法 |说明
|setCoalesing(boolen) |设置解析器CDATA结点转换成TEXT文字结点和新增在其相邻文字结点之后(如果有的话),默认为 false,true表示转换
|setExpandEntityReferencedes(boolen) |设置解析器展开实体参考的结点,默认为true表示展开,false表示不展开
|setIgnoreComments(boolen) |设置解析器忽略注释文字,默认为false,true表示不忽略
|SetIgnoringElementContentWhitespace(boolen) |设置解析器忽略元素内容为whitespace空白字节的结点,默认为false,true表示忽略
访问XML元素和属性
XML文档中常见的结点类型
结点类型|说明
NODE_DOCUMENT_TYPE|
NODE_PROCESSING_INSTRUCTION|
使用DOM创建XML文档
1) 创建XML文档
Document document = db.newDocument();
2) 创建新的结点
方法 |说明
createElement(string) | 建立XML元素的结点,参数为标记名称
createAttribute(string) | 建立属性名称的属性结点,参数是属性名称
createCDATASection(string) | 建立CDATA块,参数是文字内容
createComment(string) | 建立注释文字结点,参数为注释文字内容
createTextNode(string) | 建立文字结点,参数为内容
createEntityReference(string) | 建立实体参考,参数为实体参考名称
createProcessingInstring(string,string) | 建立PI结点,第一个参数是PI名称,第二个为值
3) 指定插入位置
在建立好XML元素的对象后,可以使用Node结点对象的方法添加到DOM树中
appendChild(newnode),新添加一个newnode结点
insertBefore(newnode,befnode),将newnode结点插到befnode结点前
4) 新增元素内容
使用createTextNode方法建立文字结点后,再使用appendChild方法将它添加到元素结点中。
5) 新增元素属性
可使用setAttribute方法给Element元素对象增加属性
6) 删除元素或属性
如果删除节点可使用Node结点的removeChild方法删除指定的结点,如果删除属性可使用Element元素对象的removeAttribute方法删除。
示例代码
Element name = document.createElementNS("","name"); // Element元素
name.setTextContent(shiptoMap.get("name")); // 添加内容
shipto.appendChild(name); // 将name添加到shipto结点
Element order = document.createElementNS("","order");
order.setAttributeNS("","orderid","20160101"); // 添加属性 Element继承于Node有此方法,Node无此方法
Node title = document.createElementNS("","title"); // Node结点
title.setTextContent(map.get("title")); // 添加内容
newcd.appendChild(title); // 将title结点添加到CD结点
root.removeChild(cd); // 删除结点
以下为具体实例
package xmlwork;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
public class sax {
/** * 解析XML * @param filepath * @return */
public Document analysis(String filepath) {
Document document = null;
File file = new File(filepath);
if(!file.exists()){
System.out.println("File is wrong!");
return null;
}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.parse(file);
} catch (ParserConfigurationException | SAXException | IOException e) {
// TODO Auto-generated catch block
System.out.println("Analysis is wrong!");
e.printStackTrace();
return null;
}
return document;
}
/** * 新增订单信息 * @param filepath * @param orderMap * @param shiptoMap * @param list */
@SuppressWarnings("unused")
private void insertOrder(String filepath,HashMap<String,String> orderMap,String> shiptoMap,List<HashMap<String,String>> list) {
// TODO Auto-generated method stub
Document document = analysis(filepath);
Element root = null;
if(document!=null){
root = document.getDocumentElement();
Element order = document.createElementNS("","order");
order.setAttributeNS("",orderMap.get("orderid"));
order.setAttributeNS("","orderdate",orderMap.get("orderdate"));
Element orderperson = document.createElementNS("","orderperson");
orderperson.setTextContent(orderMap.get("orderperson"));
Element shipto = document.createElementNS("","shipto");
Element name = document.createElementNS("","name");
Element address = document.createElementNS("","address");
Element city = document.createElementNS("","city");
Element country = document.createElementNS("","country");
Element phone = document.createElementNS("","phone");
name.setTextContent(shiptoMap.get("name"));
address.setTextContent(shiptoMap.get("address"));
city.setTextContent(shiptoMap.get("city"));
country.setTextContent(shiptoMap.get("country"));
phone.setTextContent(shiptoMap.get("phone"));
shipto.appendChild(name);
shipto.appendChild(address);
shipto.appendChild(city);
shipto.appendChild(country);
shipto.appendChild(phone);
Element items = document.createElementNS("","items");
for(HashMap<String,String>itemMap : list){
Element item = document.createElementNS("","item");
Element title = document.createElementNS("","title");
Element id = document.createElementNS("","id");
Element quantity = document.createElementNS("","quantity");
Element price = document.createElementNS("","price");
title.setTextContent(itemMap.get("title"));
id.setTextContent(itemMap.get("id"));
quantity.setTextContent(itemMap.get("quantity"));
price.setTextContent(itemMap.get("price"));
item.appendChild(title);
item.appendChild(id);
item.appendChild(quantity);
item.appendChild(price);
items.appendChild(item);
}
order.appendChild(orderperson);
order.appendChild(shipto);
order.appendChild(items);
root.appendChild(order);
System.out.println("已添加订单");
}
//执行写入文件
if(!saxToxml(root,filepath))System.out.println("写入文件出错!");
}
/** * 添加一张CD(唱片)信息 * @param filepath * @param map */
@SuppressWarnings("unused")
private void insertCD(String filepath,String> map) {
// TODO Auto-generated method stub
Document document = analysis(filepath);
Node root = null;
if(document!=null){
root = document.getDocumentElement();
Node newcd = document.createElementNS("","cd");
Node title = document.createElementNS("","title");
title.setTextContent(map.get("title"));
Node artist = document.createElementNS("","artist");
artist.setTextContent(map.get("artist"));
Node country = document.createElementNS("","country");
country.setTextContent(map.get("country"));
Node company = document.createElementNS("","company");
company.setTextContent(map.get("company"));
Node price = document.createElementNS("","price");
price.setTextContent(map.get("price"));
Node year = document.createElementNS("","year");
year.setTextContent(map.get("year"));
Node photo = document.createElementNS("","photo");
photo.setTextContent(map.get("photo"));
Node quantity = document.createElementNS("","quantity");
quantity.setTextContent(map.get("quantity"));
root.appendChild(newcd);
newcd.appendChild(title);
newcd.appendChild(artist);
newcd.appendChild(country);
newcd.appendChild(company);
newcd.appendChild(price);
newcd.appendChild(year);
newcd.appendChild(photo);
newcd.appendChild(quantity);
System.out.println("已添加 title为 "+map.get("title")+"CD条目");
}
//执行写入文件
if(!saxToxml(root,filepath))System.out.println("写入文件出错!");
}
/** * 更新一张CD(唱片)信息(根据title) * @param filepath * @param map */
@SuppressWarnings("unused")
private void updateCD(String filepath,String> map) {
// TODO Auto-generated method stub
Document document = analysis(filepath);
String str_title = map.get("title");
Node root = null;
if(document!=null){
root = document.getDocumentElement();
NodeList cds = root.getChildNodes();
for(int i=0;i<cds.getLength();i++){
boolean flag = false;
Node cd = cds.item(i);
short nodetype = cd.getNodeType();
if(nodetype==Node.ELEMENT_NODE){
if(cd.hasChildNodes()){
NodeList infos = cd.getChildNodes();
for(int j=0;j<infos.getLength();j++){
Node info = infos.item(j);
short titleType = info.getNodeType();
if(titleType==Node.ELEMENT_NODE){
if(info.getNodeName().equals("title")){
if(info.getTextContent().equals(str_title)){
flag = true;
}
}
if(flag){
if(info.getNodeName().equals("artist")){
info.setTextContent(map.get("artist"));
System.out.println("已更新title为 "+str_title+" 的CD的artist条目为"+map.get("artist"));
}
if(info.getNodeName().equals("country")){
info.setTextContent(map.get("country"));
System.out.println("已更新title为 "+str_title+" 的CD的country条目为"+map.get("country"));
}
if(info.getNodeName().equals("company")){
info.setTextContent(map.get("company"));
System.out.println("已更新title为 "+str_title+" 的CD的company条目为"+map.get("company"));
}
if(info.getNodeName().equals("price")){
info.setTextContent(map.get("price"));
System.out.println("已更新title为 "+str_title+" 的CD的price条目为"+map.get("price"));
}
if(info.getNodeName().equals("year")){
info.setTextContent(map.get("year"));
System.out.println("已更新title为 "+str_title+" 的CD的year条目为"+map.get("year"));
}
if(info.getNodeName().equals("photo")){
info.setTextContent(map.get("photo"));
System.out.println("已更新title为 "+str_title+" 的CD的photo条目为"+map.get("photo"));
}
if(info.getNodeName().equals("quantity")){
info.setTextContent(map.get("quantity"));
System.out.println("已更新title为 "+str_title+" 的CD的quantity条目为"+map.get("quantity"));
}
}
}
}
}
}
}
}
//执行写入文件
if(!saxToxml(root,filepath))System.out.println("写入文件出错!");
}
/** * 删除一条CD(唱片)信息(根据title) * @param filepath * @param map */
@SuppressWarnings("unused")
private void deleteCD(String filepath,String> map) {
// TODO Auto-generated method stub
Document document = analysis(filepath);
String str_title = map.get("title");
Node root = null;
if(document!=null){
root = document.getDocumentElement();
NodeList cds = root.getChildNodes();
for(int i=0;i<cds.getLength();i++){
Node cd = cds.item(i);
short nodetype = cd.getNodeType();
if(nodetype==Node.ELEMENT_NODE){
if(cd.hasChildNodes()){
NodeList infos = cd.getChildNodes();
for(int j=0;j<infos.getLength();j++){
Node info = infos.item(j);
short titleType = info.getNodeType();
if(titleType==Node.ELEMENT_NODE){
if(info.getNodeName().equals("title")){
if(info.getTextContent().equals(str_title)){
root.removeChild(cd);
System.out.println("已删除 title为 "+str_title+" CD条目");
}
}
}
}
}
}
}
}
//执行写入文件
if(!saxToxml(root,filepath))System.out.println("写入文件出错!");
}
/** * 将document信息写入到文件中 * @param root * @param filepath * @return */
private boolean saxToxml(Node root,String filepath) {
// TODO Auto-generated method stub
StringWriter stringWriter = new StringWriter();
SAXTransformerFactory sff = null;
TransformerHandler handler = null;
Transformer transformer = null;
StreamResult result = null;
try {
sff = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
handler = sff.newTransformerHandler();
transformer = handler.getTransformer();
//设置编码格式
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
//设置自动添加空白
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
transformer.setOutputProperty(OutputKeys.VERSION,"1.0");
//保存XML
result = new StreamResult(stringWriter);
handler.setResult(result);
//开始XML
handler.startDocument();
//设置属性
AttributesImpl attrsImpl = new AttributesImpl();
attrsImpl.clear();
handler.startElement("","",root.getNodeName(),null);
handler = getChilds(handler,attrsImpl,root.getChildNodes());
handler.endElement("",root.getNodeName());
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(stringWriter.toString());
try {
FileOutputStream out = new FileOutputStream(new File(filepath));
out.write(stringWriter.toString().getBytes());
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
/** * 递归遍历子节点 * @param handler * @param attrsImpl * @param nodelist * @return */
private TransformerHandler getChilds(TransformerHandler handler,AttributesImpl attrsImpl,NodeList nodelist) {
// TODO Auto-generated method stub
try {
for(int m=0;m<nodelist.getLength();m++){
Node node = nodelist.item(m);
short nodetype = node.getNodeType(); //得到节点的类型,可以是ElementNode,TextNode,DocumentNode等
//System.out.println("name="+node.getNodeName());
if(nodetype==Node.ELEMENT_NODE){
//遍历属性
if(node.hasAttributes()){
NamedNodeMap attrs = node.getAttributes();
for(int i=0;i<attrs.getLength();i++){
attrsImpl.addAttribute("",attrs.item(i).getNodeName(),attrs.item(i).getNodeValue());
}
}
handler.startElement("",node.getNodeName(),attrsImpl);
attrsImpl.clear();
//遍历子节点
if(node.hasChildNodes()){
handler = getChilds(handler,node.getChildNodes());
}else{
handler.characters(node.getTextContent().tocharArray(),0,node.getTextContent().length());
// System.out.println("==TextContent="+node.getTextContent());
}
handler.endElement("",node.getNodeName());
}
//Text类型节点没有子节点,节点名字为#test,节点值为XML文档中元素的值
if(nodetype==Node.TEXT_NODE){
Node parent = node.getParentNode();
Node txtnode = parent.getChildNodes().item(0);
handler.characters(txtnode.getNodeValue().tocharArray(),txtnode.getNodeValue().length());
// System.out.println("TEXT_NODE="+txtnode.getNodeValue().trim());
}
}
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return handler;
}
private void queryOrder(String filepath,String time) {
// TODO Auto-generated method stub
int ordernum=0;
int quantity=0,sum = 0;
float price=0.0F;
Document document = analysis(filepath);
Node root = null;
boolean flag = false;
if(document!=null){
root = document.getDocumentElement();
NodeList orders = root.getChildNodes();
for(int i=0;i<orders.getLength();i++){
Node order = orders.item(i);
//遍历属性
if(order.hasAttributes()){
NamedNodeMap attrs = order.getAttributes();
for(int m=0;m<attrs.getLength();m++){
if(attrs.item(m).getNodeName().equals("orderdate")){
//年月一样,遍历Ite并得到总价
if(attrs.item(m).getNodeValue().contains(time)){
System.out.println("Time:"+attrs.item(m).getNodeValue());
flag = true;
ordernum++;
}
}
}
if(!flag)continue;
NodeList infos = order.getChildNodes();
for(int j=0;j<infos.getLength();j++){
Node info = infos.item(j);
if(!info.getNodeName().equals("items"))continue;
NodeList items = info.getChildNodes();
for(int k=0;k<items.getLength();k++){
NodeList properties = items.item(k).getChildNodes();
for(int m=0;m<properties.getLength();m++){
Node nodeQ = properties.item(m);
if(nodeQ.getNodeType()==Node.ELEMENT_NODE){
if(nodeQ.getNodeName().equals("quantity")){
// System.out.println(nodeQ.getNodeName()+"=="+nodeQ.getTextContent());
quantity = Integer.parseInt(nodeQ.getTextContent());
}
if(nodeQ.getNodeName().equals("price")){
// System.out.println(nodeQ.getNodeName()+"=="+nodeQ.getTextContent());
price = Float.parseFloat(nodeQ.getTextContent());
}
}
}
sum+=quantity*price;
quantity=0;
price=0;
}
}
}
}
System.out.println(time+"月共有"+ordernum+"个订单,交易金额为"+sum+"元");
}
}
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("title","36");
map.put("artist","11");
map.put("country","11");
map.put("price","11");
map.put("year","15");
map.put("photo","15");
//测试新增CD信息
// new sax().insertCD("G://disc.xml",map);
//测试更新CD信息
// new sax().updateCD("G://disc.xml",map);
//测试删除CD信息
// new sax().deleteCD("G://disc.xml",map);
HashMap<String,String> orderMap = new HashMap<String,String>();
orderMap.put("orderid","2013264444203");
orderMap.put("orderdate","2021-05-05");
orderMap.put("orderperson","coffee");
HashMap<String,String> shiptoMap = new HashMap<String,String>();
shiptoMap.put("name","Licy");
shiptoMap.put("address","贝利街");
shiptoMap.put("city","纽约");
shiptoMap.put("country","美国");
shiptoMap.put("phone","11123459999");
List<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
HashMap<String,String> item1 = new HashMap<String,String>();
item1.put("title","狗镇");
item1.put("id","2937774");
item1.put("quantity","377373");
item1.put("price","233.00");
HashMap<String,String> item2 = new HashMap<String,String>();
item2.put("title","夏洛特烦恼");
item2.put("id","445645");
item2.put("quantity","6664444");
item2.put("price","444.44");
list.add(item1);
list.add(item2);
//测试新增订单信息
// new sax().insertOrder("G://order.xml",orderMap,shiptoMap,list);
new sax().queryOrder("G://order.xml","2015-11");
}
}
XML order.xml文件信息
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="order.xslt"?>
<shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="shiporder.xsd">
<order orderid="2015261020278" orderdate="2015-11-20">
<orderperson>cs</orderperson>
<shipto>
<name>coffee</name>
<address>师范学院</address>
<city>鄂州</city>
<country>中国</country>
<phone>13094278550</phone>
</shipto>
<items>
<item>
<title>权利的游戏</title>
<id>20151120</id>
<quantity>1</quantity>
<price>200.00</price>
</item>
</items>
</order>
<order orderid="2015261020206" orderdate="2015-12-12">
<orderperson>李磊</orderperson>
<shipto>
<name>ivan</name>
<address>师范学院</address>
<city>武汉</city>
<country>中国</country>
<phone>13298845263</phone>
</shipto>
<items>
<item>
<title>硅谷之火</title>
<id>250144</id>
<quantity>1</quantity>
<price>245.00</price>
</item>
<item>
<title>暗黑者</title>
<id>36254</id>
<quantity>2</quantity>
<price>123.00</price>
</item>
</items>
</order>
</shiporder>
XML disc.xml信息
<?xml version="1.0" encoding="UTF-8"?>
<cdcatalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="cdcatalog.xsd">
<cd>
<title>准备中</title>
<artist>张智霖</artist>
<country>中国香港</country>
<company></company>
<price>499.00</price>
<year>2008</year>
<photo>12345678901</photo>
<quantity>1000000</quantity>
</cd>
<cd>
<title>21</title>
<artist>Adele</artist>
<country>美国</country>
<company>XL Recordings、Columbia </company>
<price>222.00</price>
<year>2011</year>
<photo>13456789001</photo>
<quantity>1000000</quantity>
</cd>
<cd>
<title>25</title>
<artist>Adele</artist>
<country>美国</country>
<company>XL Recordings、Columbia </company>
<price>222.00</price>
<year>2015</year>
<photo>13207873749</photo>
<quantity>1000000</quantity>
</cd>
</cdcatalog>