闲聊下Java与XML互转的N种实现方式
来源:互联网 发布:中世纪2 优化9 兵种 编辑:程序博客网 时间:2024/04/29 21:23
最近又用到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等
- 闲聊下Java与XML互转的N种实现方式
- View动画的XML与Java代码实现的两种方式,交叉着用
- xstream : 实现XML 与 Java Object的互转
- Castor实现XML与Java的互转
- Java解析XML的四种方式详解与比较
- 闲聊Java里的随机数
- Quartz xml实现方式下修改配置文件的路径
- 最原始的方式实现String与xml的转换
- 【闲聊】IE浏览器的辉煌与落寞
- JAXB实现xml与java对象的
- 闲聊Mysql的锁与事务和java中的锁机制
- java解析xml的几种方式(转)
- java解析xml的几种方式(转)
- Java解析XML的四种方式
- Java读取xml的四种方式
- JAVA XML 解析的四种方式
- Java读取xml的四种方式
- java解析xml的几种方式
- Maven部署Web项目报错webxml attribute is required
- 书写优雅的shell脚本(七)- ${COLUMN:-}
- lua学习笔记13:协程详解和举例
- PHP在指定的预定义字符前添加反斜杠
- 类和对象第二讲
- 闲聊下Java与XML互转的N种实现方式
- 深入浅出Swift(4)—— TableView
- 无线电波的波段划分和应用
- 安装redis之前必须安装哪些套件
- 数据结构绪论
- 【贪心】【Uva11292】 勇者斗恶龙
- DropDownCheckBoxes 控件
- Edit Distance
- vi / vim 删除以及其它命令