针对xml文件做提取与写入的操作
解析xml的底层接口:一种是dom,一种是sax。
DOM与SAX的区别。
DMO:dom解析xml时,首先是将xml文档的内容整个加载到内存中,并解析成树形结构。然后开始随机访问内存中的对橡树。所以当xml文件比较大的时候,效率就会降低,还可能发生内存溢出。
SAX:是基于事件而且是顺序解析,不会一次性将内容解析完。而是读到什么标签时,调用相应的方法去解析。缺点就是不可逆,一个元素错过之后就没法返回再次解析。但是由于不会事先将内容加载到内存中所以对内存的占用非常小。虽然SAX在开发上比dom要稍微复杂点,需要开发者自己实现事件处理器,但是也正是应为交由开发者自己处理也将变得更加灵活。
DOM
public class Demo { public static void main(String[] args) throws Exception { //获得一个从xml文档生成dom对象的一个解析器 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //创建dom实例的API DocumentBuilder db = dbf.newDocumentBuilder(); //将给定的文件解析成xml文档,并返回一个新的dom对象 Document doc = db.parse(new File("dubbo.xml")); //输出文档属性,并返回成一个元素集合点实例 Element eoc = doc.getDocumentElement(); parseElement(eoc); } private static void parseElement(Element element) { //输出元素集合中第一个节点的节点名 String name = element.getNodeName(); System.out.println("<" + name); //输出节点属性,返回一个map实例 NamedNodeMap map = element.getAttributes(); if (null != map) { //输出节点属性中 每个属性的name与value for (int i = 0; i < map.getLength(); i++) { Attr attr = (Attr)map.item(i); String attrName = attr.getName(); String attrValue = attr.getValue(); System.out.println("" + attrName + "=\""+attrValue+"\""); } } System.out.println(">"); //getChildNodes 返回当前节点下所有的子节点,而dom默认认为换行也是一个节点。所以会出现#test这样的输出(换行导致) NodeList child = element.getChildNodes(); for (int i = 0; i < child.getLength(); i++) { Node node = child.item(i); //TEXT_NODE-文字节点类型 //DOCUMENT_NODE-文本节点类型 //COMMENT_NODE-注释节点类型 //ATTRIBUTE_NODE-属性节点类型 //ELEMENT_NODE-元素节点类型 Short noteType = node.getNodeType(); if (noteType == Node.ELEMENT_NODE) { parseElement((Element)node); } else { if (noteType == Node.TEXT_NODE) { System.out.println(node.getTextContent()); } else { if (noteType == Node.COMMENT_NODE) { System.out.println("<!--"+node.getTextContent() + "-->"); } } } } System.out.println("</" +name+ ">"); } }
SAX
public class SAXHandler extends DefaultHandler{ private String currentElement; private String currentValue; private String attrName; private String attrValue; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { currentElement = qName; for (int i = 0; i < attributes.getLength(); i++) { attrName = attributes.getQName(i); attrValue = attributes.getValue(i); System.out.println("属性:" + attrName + "=" + attrValue); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { currentValue = new String(ch,start,length); System.out.println("characters开始" + currentValue); } @Override public void endElement(String uri, String localName, String qName) { if (currentElement.equals(qName)) { System.out.println(currentElement + "=" + currentValue); } } } public static void main(String[] args) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); SAXHandler handler = new SAXHandler(); sp.parse(new File("dubbo.xml"), handler); }
而jdom和dom4j则是针对底层接口的延伸,且这2个接口都只是面向java语言。
jdom
dom4j
上诉这3个方式都封装好了对xml文件的操作功能,而且基本的方法都大同小异。
由于jdom对于大型的xml文件存在内存溢出的问题,所以现在市面上比较流行的是dom4j的方式来操作。
但实际上dom4j最早只是一个jdom的延伸,当初jdom由于是针对实现变成,灵活性不足,所以才有了后来的dom4j。