JAXP进行DOM解析的实践
Posted 幽幽子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAXP进行DOM解析的实践相关的知识,希望对你有一定的参考价值。
比较重要的几个类,使用频率比较高的就是Document, Element与Node.
几个常用的套路:
static { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); builder = dbFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } }
当需要进行增删改的操作时:
/** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result);
整个代码:
package com.changjiang.test.RFP01.testXML; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class JaxpDemo { private static DocumentBuilder builder; static { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); builder = dbFactory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } } public static void printLine() { System.out.println("===================================================="); } /** * 根据标签名称获得标签里内容,越过了层级 * * @param document */ public static void getContentFromNode(Document document) { NodeList nl = document.getElementsByTagName("作者"); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); System.out.println(n.getTextContent()); } } /** * 获取根节点 * * @param document */ public static void getRootNode(Document document) { System.out.println(document.getDocumentElement().getTagName()); } public static void getAllNodes(Node node) { /** * 确定是否为元素 */ if (node.getNodeType() == Node.ELEMENT_NODE) { System.out.println("node.getNodeType()==Node.ELEMENT_NODE 判断为元素"); } if (node instanceof Element) { System.out.println("node instanceof Element 判断为元素"); Element e = (Element) node; System.out.println(e.getNodeName()); } NodeList nl = node.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node childNode = nl.item(i); getAllNodes(childNode); } } /** * 更新节点内容 * * @param document * @throws TransformerException */ public static void modifyNodeContent(Document document) throws TransformerException { Node priceNode = document.getElementsByTagName("售价").item(0); priceNode.setTextContent("55"); /** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result); } /** * 添加节点到同级目录的结尾 * * @param document * @throws TransformerException */ public static void addNode(Document document) throws TransformerException { Element e = document.createElement("年代"); e.setTextContent("2014"); Node n = document.getElementsByTagName("书").item(0); n.appendChild(e); /** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result); } /** * 添加节点到指定的同级节点之前 * @param document * @throws TransformerException */ public static void addBeforeNode(Document document) throws TransformerException { Element e = document.createElement("年代"); e.setTextContent("2014"); /** * 父节点.insertBefore(新节点,参考节点) */ Node n = document.getElementsByTagName("书名").item(0); Node parent = n.getParentNode(); parent.insertBefore(e, n); /** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result); } /** * 删除指定元素节点 * * @throws TransformerException */ public static void deleteNode(Document document) throws TransformerException { Node yearNode = document.getElementsByTagName("年代").item(0); yearNode.getParentNode().removeChild(yearNode); /** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result); } /** * 获取节点的属性 * * @param document */ public static void getNodeAttribute(Document document) { Node bookNode = document.getElementsByTagName("书").item(0); if (bookNode instanceof Element) { Element e = (Element) bookNode; System.out.println(e.getAttribute("ISBN")); } } /** * 重新设置节点属性的内容 * @param document * @throws TransformerException */ public static void setNodeAttribute(Document document) throws TransformerException { Node bookNode = document.getElementsByTagName("书").item(0); if (bookNode instanceof Element) { Element e = (Element) bookNode; e.setAttribute("ISBN", "RFW000001"); } /** * 获取更新对象 */ TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); /** * 构建源与目标 */ Source source = new DOMSource(document); Result result = new StreamResult("src/main/resources/book.xml"); tf.transform(source, result); } }
DOM解析时,整个XML文件会被加载到内存中,所以当XML文件特别大时,会造成内存的溢出。
针对这种情况,SAX解析可以做到在读取XML文档时,就对文档内容进行处理,而不必等到整个文件装载完毕才对文件进行操作。
=================================================>
SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器: 解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。 解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法 时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。 事件处理器由程序员编写,程序员通过事件处理器中方法的参数(比较重要的方法-startElement,endElement,characters),就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。(需要用到时再具体了解)
=================================================>
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽 象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。 Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了 Dom4j。 使用Dom4j开发,需下载dom4j相应的jar文件。(需要用到时再具体了解)
以上是关于JAXP进行DOM解析的实践的主要内容,如果未能解决你的问题,请参考以下文章
使用 XSD、目录解析器和用于 XSLT 的 JAXP DOM 验证 XML