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文档,首先获取根节点,然后获得根结点的子结点列表
设定加载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>