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解析的实践的主要内容,如果未能解决你的问题,请参考以下文章

jaxp使用笔记

使用 XSD、目录解析器和用于 XSLT 的 JAXP DOM 验证 XML

XML解析器之JAXP与DOM4J

javaweb学习总结十二(JAXP对XML文档进行SAX解析)

解析xml

XML解析——jaxp