• Java原生API操作XML


    使用Java操作XML的开源框架比较多,如著名的Dom4J、JDOM等,但个人认为不管你用那个框架都要对JDK原生的API有所了解才能更得心应手的应用。本篇就来简单了解下原生的XML API。

    JAVA的XML API

    XML的开放性和Java的开源性注定它们是一种完美结合,因此Sun提供了一套专门用于处理XML的Java API:JAXP,JAXP遵循XML的两种解析标准:DOM(Document Object Model)和SAX(Simple API for XML Parsing),JAXP也支持XSLT(XML Stylesheet Language Transformation)标准,可控制数据的表现形式和XML文档与HTML等其他文档之间的数据转换。

    • DOM是对对文档结构及其内容的树形描述,该模型中的每个节点对应XML文档中的各种组成部分。使用DOM树,应用程序可以反复访问其中的某个节点、可以增加、删除、修改节点。DOM树中的节点分为两大类型:元素节点和文本节点。以DOM方式解析XML有以下优点:

      1. DOM将文本文件转化为抽象的树节点表示,能够避免文档在语法方面的错误,从而保证正确的语法和格式的正规性;
      2. DOM创建的节点树是对XML文档内容及其逻辑关系的正确反映,因而它是从XML语法规范中抽取内容而又高于语法约束的;同时,也使得对DOM树进行修改比修改XML文档本身要简单得多;
      3. DOM树不仅能够如实反映XML文档本身的层次结构,还可以很好地反映关系数据库中具有雪花结构的层次信息;
    • SAX不同于DOM,严格来说它并不是一种规范或标准。SAX解析是一种以时间驱动的流式解析,解析过程中按文档中的元素出现顺序逐个访问和处理元素。由于对XML文档组成部分的访问是一次性的,使用SAX时,解析器想应用程序报告解析事件流,来告知应用程序文档的内容。SAX解析方式具有以下特点:

      1. 对所解析的XML文件没有大小限制:由于SAX无须将整个XML文档载入内存,且处理时对内存占用并不随处理XML文档的大小而变化,因而对被处理文件的大小没要求;
      2. 简单易用;
      3. 处理速度快:由于以时间驱动的方式进行文档处理,无须对某个对象进行反复处理,因而速度很快;
      4. 不能对文档的组成部分进行随机存取:因为文档并没有载入内存,其处理是流式的,因而也难以实现对文档做复杂的查询;

      总体来说SAX解析占用的内存少,速度快,适用于对文档进行一次性处理情况。

    JAXP的主要API都定义在javax.xml.parsers中,该包为开发SAX解析器和DOM解析器提供了公共接口:

    • 包org.w3c.dom负责以DOM方式解析;
    • 包org.xml.sax负责定义SAX API;
    • 包javax.xml.transform定义了将XML转换为其他形式的XSLT API;

    解析示例

    oseye.xml

    <?xml version="1.0"?>
    <note>
    	<to>oseye.net</to>
    	<from>kevin</from>
    	<heading>Reminder</heading>
    	<body>Don't forget the meeting!</body>
    </note>

    Dom方式解析

    package com.byd.DomXML;
    
    import java.io.File;
    import java.io.IOException;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.SAXException;
    
    /**
     * Dom方式解析XML
     */
    public class App {
    	public static void main(String[] args) throws ParserConfigurationException,
    			SAXException, IOException {
    		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    		DocumentBuilder bulder = factory.newDocumentBuilder();
    		Document doc = bulder.parse(new File("d:/mytemp/xml/oseye.xml"));
    		// 获取根元素
    		Element element = doc.getDocumentElement();
    		NodeList list = element.getChildNodes();
    		for (int iloop = 0; iloop < list.getLength(); iloop++) {
    			Node node = list.item(iloop);
    			if (node.getNodeType() == Node.ELEMENT_NODE) {
    				System.out.println(node.getNodeName() + ":"
    						+ node.getTextContent());
    			}
    		}
    	}
    }

    SAX方式解析

    package com.byd;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    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;
    
    /**
     * SAX方式解析
     */
    public class App 
    {
        public static void main( String[] args ) throws Exception
        {
            SAXParserFactory factory=SAXParserFactory.newInstance();
            SAXParser sparse=factory.newSAXParser();
            SaxHandler handler=new SaxHandler("note");
            sparse.parse(new File("d:/mytemp/xml/oseye.xml"),handler);
            //输出
            for(Map<String,String> map:handler.getList()){
            	Iterator<String> iterator=map.keySet().iterator();
            	while(iterator.hasNext()){
            		String key=iterator.next();
            		System.out.println(key+":"+map.get(key));
            	}
            }
        }
    }
    
    class SaxHandler extends DefaultHandler {  
        private HashMap<String, String> map = null;  
        private List<HashMap<String, String>> list = null;  
        //正在解析的元素的标签 
        private String currentTag = null;  
        //正在解析的元素的值  
        private String currentValue = null;  
        private String nodeName = null;  
          
        public List<HashMap<String, String>> getList(){  
            return list;  
        }  
      
        public SaxHandler(String nodeName) {  
            this.nodeName = nodeName;  
        }  
      
        @Override  
        public void startDocument() throws SAXException {  
            //当读到一个开始标签的时候,会触发这个方法  
            list = new ArrayList<HashMap<String,String>>();  
        }  
      
        @Override  
        public void startElement(String uri, String localName, String name,  
                Attributes attributes) throws SAXException {  
            //当遇到文档的开头的时候,调用这个方法  
            if(name.equals(nodeName)){  
                map = new HashMap<String, String>();  
            }  
            if(attributes != null && map != null){  
                for(int i = 0; i < attributes.getLength();i++){  
                    map.put(attributes.getQName(i), attributes.getValue(i));  
                }  
            }  
            currentTag = name;  
        }  
          
        @Override  
        public void characters(char[] ch, int start, int length)  
                throws SAXException {  
            //这个方法用来处理在XML文件中读到的内容  
            if(currentTag != null && map != null){  
                currentValue = new String(ch, start, length);  
                if(currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("
    ")){  
                    map.put(currentTag, currentValue);  
                }  
            }  
            currentTag=null;  
            currentValue=null;  
        }  
      
        @Override  
        public void endElement(String uri, String localName, String name)  
                throws SAXException {  
            //在遇到结束标签的时候,调用这个方法  
            if(name.equals(nodeName)){  
                list.add(map);  
                map = null;  
            }  
            super.endElement(uri, localName, name);  
        }  
    }  

    输出

    to:oseye.net
    body:Don't forget the meeting!
    from:kevin
    heading:Reminder

    以上并没有对API做详细讲解,具体API可参考JDK。

    出处:http://www.zhaiqianfeng.com    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    【BZOJ1489】[HNOI2009]双递增序列(动态规划)
    【BZOJ1488】[HNOI2009]图的同构(Burside引理,Polya定理)
    【BZOJ4888】[TJOI2017]异或和(树状数组)
    【BZOJ1487】[HNOI2009]无归岛(动态规划)
    【BZOJ1485】[HNOI2009]有趣的数列(组合数学)
    【BZOJ1484】[HNOI2009]通往城堡之路 (贪心)
    【BZOJ1452】[JSOI2009]Count(树状数组)
    【BZOJ1449】[JSOI2009]球队收益(网络流,费用流)
    【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)
    【BZOJ1434】[ZJOI2009]染色游戏(博弈论)
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620390.html
Copyright © 2020-2023  润新知