• 闲聊下Java与XML互转的N种实现方式


    最近又用到XML,发现也有必要聊聊XML的几种方式。

    1,如果只是简单生成或者解析,自己写一个帮助类就行,下面这个是我前段时间用递归写的,优势方便可以扩展

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 
     * @author hejinbin1987@163.com
     * 
     *         TODO manage node and value.and format the node to xml file
     * 
     */
    public class XMLSimpleNode implements SimpleNode {
        private String nodeName;
        private String value;
        List<SimpleNode> childs;
        private String header;
    
        public XMLSimpleNode(String nodeName) {
            this.nodeName = nodeName;
            childs = new ArrayList<SimpleNode>(2);
        }
    
        public String getNodeName() {
            return nodeName;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.benson.another.SimpleXMLFileUtil#setNodeName(java.lang.String)
         */
        public void setNodeName(String nodeName) {
            this.nodeName = nodeName;
        }
    
        public String getValue() {
            return value;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.benson.another.SimpleXMLFileUtil#setValue(java.lang.String)
         */
        public void setValue(String value) {
            this.value = value;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.benson.another.SimpleXMLFileUtil#addChild(org.benson.another.XMLItem)
         */
        public void addChild(SimpleNode node) {
            childs.add(node);
        }
    
        public String startTag() {
            StringBuffer tagSart = new StringBuffer("<");
            tagSart.append(nodeName);
            tagSart.append(">");
            return tagSart.toString();
        }
    
        public String endTag() {
            StringBuffer tagEnd = new StringBuffer("</");
            tagEnd.append(nodeName);
            tagEnd.append(">");
            return tagEnd.toString();
        }
    
        public String getHeader() {
            return header;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.benson.another.SimpleXMLFileUtil#setHeader(java.lang.String)
         */
        public void setHeader(String header) {
            this.header = header;
        }
    
        /**
         * ToDo format the node to xml file
         */
        public String formartXMLFile() {
            StringBuffer xmlFileBf = new StringBuffer();
            xmlFileBf.append(this.getHeader());
            return this.getNode(this, xmlFileBf).toString();
        }
    
        /**
         * 
         * @param node
         * @param xmlFileBf
         * @return get XML content by node
         */
        private StringBuffer getNode(SimpleNode node, StringBuffer xmlFileBf) {
            XMLSimpleNode xmlNode = (XMLSimpleNode) node;
            XMLSimpleNode xmlNodeItem = null;
            xmlFileBf.append(xmlNode.startTag());
            if (xmlNode.childs.size() != 0) {
                for (int i = 0; i < xmlNode.childs.size(); i++) {
                    xmlNodeItem = (XMLSimpleNode) xmlNode.childs.get(i);
                    getNode(xmlNodeItem, xmlFileBf);
                }
            }
            if (xmlNode.getValue() != null)
                xmlFileBf.append(xmlNode.getValue());
            xmlFileBf.append(xmlNode.endTag());
            return xmlFileBf;
        }
    
        public static void main(String[] args) {
            SimpleNode xmlNode = new XMLSimpleNode("root");
            xmlNode.setHeader("<?xml version=\"1.0\" encoding=\"UTF-8\" ?> ");
            SimpleNode chridNode1 = new XMLSimpleNode("chrid1");
            SimpleNode chridNode2 = new XMLSimpleNode("chrid2");
            SimpleNode chridNode3 = new XMLSimpleNode("chrid3");
            SimpleNode chridNode11 = new XMLSimpleNode("chrid11");
            SimpleNode chridNode12 = new XMLSimpleNode("chrid12");
            SimpleNode chridNode13 = new XMLSimpleNode("chrid13");
            chridNode11.setValue("chridNode11 Value");
            chridNode12.setValue("chridNode12 Value");
            chridNode13.setValue("chridNode13 Value");
            chridNode2.setValue("chridNode2 Value");
            chridNode3.setValue("chridNode3 value");
            chridNode1.addChild(chridNode11);
            chridNode1.addChild(chridNode12);
            chridNode1.addChild(chridNode13);
            xmlNode.addChild(chridNode1);
            xmlNode.addChild(chridNode2);
            xmlNode.addChild(chridNode3);
            System.out.println(xmlNode.formartXMLFile());
        }
    
    
    }

    输出结果如下

    <?xml version="1.0" encoding="UTF-8" ?> <root><chrid1><chrid11>chridNode11 Value</chrid11><chrid12>chridNode12 Value</chrid12><chrid13>chridNode13 Value</chrid13></chrid1><chrid2></chrid2><chrid3></chrid3></root>
    

    其实个人感觉和jdom就有点类似了,扩展下就好了

    2,用DOM,这个东西也是把XML组成树,然后放进内存中,但是遵循了w3c的原则,方便移植,兼容性好,你可以切换各种实现方式如,Xerces,或者Crimon,再或者其它,修改jaxp.propertie,JDK默认是Xerces。

    缺点也很明显,一次性加载进内存,容易造成内存溢出,API也不好用,不支持接点的随机访问

    顺便说句,最近看源码发现spring就是用这个做配置文件解析的 2. spring中IOC的实现源码篇【analyze spring framework source】,所以当spring配置文件过多时也会报out memory了

    注意:没找到?因为sun的JDK默认是不存在的,IBM的JDK存在,新建一个就行 ,

    放在  ${JAVA_HOME}/lib/jaxp.properties,

    修改成 javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl

    常见IBM JDK兼容性错误,一般也是这个原因引起:

    javax.xml.parsers.FactoryConfigurationError: Provider null could not be instantiated:         

    java.lang.NullPointerException  

    3.jdom ,这个也是基于DOM实现的,但其API比DOM好用,更灵活,不是标准W3C

    4.SAX,这个是逐行解析和构建XML文件,优点就是不用把XML整个结构都加进内存,适用于大批量的XML文件导入导出,缺点:每次都要去读文件,肯定没有直接内存里速度快了

    附上:SAXP解析XML的笔记 挺详细的

     

    5.DOM4J,原来是JDOM的分支,现独立开发,处于JDOM于SAX之间,即支持把XML放进内存,但可以读取时选择性删除DOM节点减少内存使用,所以也可以处理大数据XML文件,传说hibernate的配置文件也是基于dom4J(没看hibernate源码)

    优点,提供读取事件处理,提供Visitor处理,也可以处理大数据XML文件(每次读完节点后删除)当然处理大数据咋样也不如SAX节省内存了,毕竟要读完一个element才会触发

    百度百科的介绍的不错 http://baike.baidu.com/view/1460716.htm

    show you the code. 下面就是分别用这4中方法读写XML

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Iterator;
    import java.util.List;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import javax.xml.stream.XMLOutputFactory;
    import javax.xml.stream.XMLStreamWriter;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.dom4j.ElementHandler;
    import org.dom4j.ElementPath;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;
    import org.jdom.output.XMLOutputter;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NodeList;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    /**
     * 
     * @author Love Eat large meat bun
     * @TD use the SAX DOM JDOM to build and parser xml file
     * @email hejinbin1987@163.com
     */
    public class Test4XML extends DefaultHandler implements ElementHandler {
        private String tagName = "";
        public static final String FILE_PATH = "D://saxText.xml";
    
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            System.out.println(tagName + "===SAX===>" + new String(ch, start, length));
        }
    
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            tagName = qName;
        }
    
        public static void removeFile() {
            System.out.println("the file have be delete is " + new File(FILE_PATH).delete());
        }
    
        @Override
        public void onEnd(ElementPath paramElementPath) {
            // TODO print node 
            org.dom4j.Element ele=paramElementPath.getCurrent();
            System.out.println(ele.getName()+"===DOM4J====>"+ele.getText());
            ele.detach();//after read /root/user node .remove it from memory,avoid out of memory
        }
    
        @Override
        public void onStart(ElementPath paramElementPath) {
        }
    
        public void writeXMLByDOM() throws Exception {
            DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = buildFactory.newDocumentBuilder();
            Document doc = documentBuilder.newDocument();
            Element ele = doc.createElement("root");
            Element ele1 = doc.createElement("user");
            ele1.setTextContent("largeMeatBun");
            ele.appendChild(ele1);
            Element ele2 = doc.createElement("email");
            ele2.setTextContent("hejinbin1987@163.com");
            ele.appendChild(ele2);
            doc.appendChild(ele);
            DOMSource xmlSource = new DOMSource(doc);
            TransformerFactory transFactory = TransformerFactory.newInstance();
            Transformer transformer = transFactory.newTransformer();
            FileOutputStream outputTarget = new FileOutputStream(FILE_PATH);
            transformer.transform(xmlSource, new StreamResult(outputTarget));
            outputTarget.close();//the output steam can't auto to close
        }
    
        public void readerDOMParseXML() throws Exception {
            DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = buildFactory.newDocumentBuilder();
            FileInputStream file = new FileInputStream(FILE_PATH);
            Document document = documentBuilder.parse(file);
            file.close();//the xml data have load in memory
            Element node = document.getDocumentElement();
            NodeList nodelist = node.getChildNodes();
            for (int i = 0; i < nodelist.getLength(); i++)
                System.out.println(nodelist.item(i).getNodeName() + "===DOM===>" + nodelist.item(i).getTextContent());
        }
    
        public void writeXMLBySAX() throws Exception {
            //sax writer
            OutputStream SAXOut = new FileOutputStream(FILE_PATH);
            XMLStreamWriter xmlWrite = XMLOutputFactory.newInstance().createXMLStreamWriter(SAXOut);
            xmlWrite.writeStartDocument("utf-8", "1.0");
            xmlWrite.writeStartElement("root");
            xmlWrite.writeStartElement("user");
            xmlWrite.writeCharacters("largeMeatBun");
            xmlWrite.writeEndElement();
            xmlWrite.writeStartElement("email");
            xmlWrite.writeCharacters("hejinbin1987@163.com");
            xmlWrite.writeEndElement();
            xmlWrite.writeEndElement();
            xmlWrite.writeEndDocument();
            xmlWrite.close();
            SAXOut.close();
        }
    
        public void parseXMLbySAX() throws Exception {
            //sax parser
            InputStream SAXIn = new FileInputStream(FILE_PATH);
            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
            saxParser.parse(SAXIn, this);
        }
    
        public org.jdom.Document readXMLByJDOM() throws Exception {
            FileInputStream JDOMInput = new FileInputStream(FILE_PATH);
            org.jdom.Document doc = new SAXBuilder().build(JDOMInput);
            org.jdom.Element eleRoot = doc.getRootElement();
            List<org.jdom.Element> eleJDOMList = eleRoot.getChildren();
            for (org.jdom.Element eleJDOM : eleJDOMList) {
                System.out.println(eleJDOM.getName() + "====JDOM===>" + eleJDOM.getText());
            }
            return doc;
        }
    
        public void writeXMLByJDOM(org.jdom.Document doc) throws Exception {
            FileOutputStream JDOMOut = new FileOutputStream(FILE_PATH);
            new XMLOutputter().output(doc, JDOMOut);
            JDOMOut.close();
        }
    
        public org.dom4j.Document readXMLByDOM4J() throws Exception {
            SAXReader saxReadernew =new SAXReader();
            saxReadernew.addHandler("/root/user", this);
            org.dom4j.Document docD4J = saxReadernew.read(FILE_PATH);
            org.dom4j.Element rootD4E = docD4J.getRootElement();
            Iterator<org.dom4j.Element> iterD4E = rootD4E.elementIterator();
            while (iterD4E.hasNext()) {
                org.dom4j.Element eleD4E = iterD4E.next();
                System.out.println(eleD4E.getName() + "===DOM4J===>" + eleD4E.getText());
            }
            return docD4J;
        }
    
        public void writeXMLByDOM4J(org.dom4j.Document docD4J) throws Exception {
            FileOutputStream DOM4JOut = new FileOutputStream(FILE_PATH);
            XMLWriter writer = new XMLWriter(DOM4JOut);
            writer.write(docD4J);
            DOM4JOut.close();
        }
    
        public static void main(String[] args) throws Exception {
    
            /**
             * dom you can change the implement class any one you like in jaxp.properties
             */
            //dom writer and parser
            Test4XML test4Xml = new Test4XML();
            test4Xml.writeXMLByDOM();
            test4Xml.readerDOMParseXML();
    
            /**
             * SAX help doc http://doc.java.sun.com/DocWeb/api/all/javax.xml.stream.XMLStreamWriter
             */
            removeFile();
            test4Xml.writeXMLBySAX();
            test4Xml.parseXMLbySAX();
    
            /**
             * @see http://www.jdom.org/ to find api on jdom web
             */
            org.jdom.Document doc = test4Xml.readXMLByJDOM();
            removeFile();
            test4Xml.writeXMLByJDOM(doc);
    
            /**
             * @see http://www.dom4j.org/
             */
            org.dom4j.Document docDOM4J = test4Xml.readXMLByDOM4J();
            test4Xml.writeXMLByDOM4J(docDOM4J);
    //        removeFile();
        }
    
    }

     

    6.其它开源项目,比如xstream等

     

  • 相关阅读:
    九九乘法表
    User-Agent的获取方法
    web前端【第一篇】HTML基础一(标签)
    SQLAlchemy的简单使用
    MongoDB的简单使用
    redis简单使用
    MySQL数据库学习【第十二篇】pymysql模块
    MySQL数据库学习【第十一篇】IDE工具介绍及数据备份
    MySQL数据库学习【第十篇】(视图、触发器、事物)
    MySQL数据库学习【补充】mysql老是停止运行该怎么解决
  • 原文地址:https://www.cnblogs.com/springsource/p/2875327.html
Copyright © 2020-2023  润新知