SAX解析XML教程

SAX解析XML教程

加载XML文档文件

  1. 首先导入相关套件
import org.xml.sax.*;
  1. 在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,HashMap<String, 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("", "orderid",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,HashMap<String, 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,HashMap<String, 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,HashMap<String, 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,attrsImpl,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(),0,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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值