XML文件解析之DOM解析

XML文件是一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。基本的解析方式包括DOM解析和SAX解析,具体来说包括DOM解析,SAX解析,DOM4J解析以及JDOM解析,首先来讲下DOM解析的具体实现方式:

1.重要的对象

DocumentBuilderFactory: 创建文档解析器的工厂对象

DocumentBuilder :得到文档解析器对象,由工长对象获取

Document :文档对象

2.解析XML实现方式

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<world>
    <comuntry id="1">
        <name>China</name>
        <capital>Beijing</capital>
        <population>1234</population>
        <area>960</area>
    </comuntry>
    <comuntry id="2">
        <name id="">America</name>
        <capital>Washington</capital>
        <population>234</population>
        <area>900</area>
    </comuntry>
    <comuntry id="3">
        <name >Japan</name>
        <capital>Tokyo</capital>
        <population>234</population>
        <area>60</area>
    </comuntry>
    <comuntry id="4">
        <name >Russia</name>
        <capital>Moscow</capital>
        <population>34</population>
        <area>1960</area>
    </comuntry>
</world>

3.解析XML实现方式

       1.获得DocumentBuilderFactory 

      2.获得DocumentBuilder

     3.读取文件的输入流

     4.获得文档的根元素调用递归函数进行处理

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMParse {

    /**
     * 1.获得DocumentBuilderFactory
     * 2.获得DocumentBuilder
     * 3.读取文件的输入流
     * 4.获得文档的根元素调用递归函数进行处理
     * @param args
     */
    public static void main(String[] args) {

        //获得DocumentBuilderFactory
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            //获得DocumentBuilder
            DocumentBuilder documentBuilder = factory.newDocumentBuilder();
            //读取文件的输入流
            InputStream inputStream = new FileInputStream(new File("world.xml"));
            //获得文档对象
            Document document = documentBuilder.parse(inputStream);
            //获得文档的根元素
            Element rootElement = document.getDocumentElement();
            listChildNodes(rootElement,0);
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 递归遍历并打印所有的ElementNode(包括节点的属性)
     * 1.首先处理该节点信息
     * 2.处理节点的属性信息
     * 3.处理子节点(递归方法实现)
     * @param node   表示节点对象
     * @param level  节点所处的层次(从第一层根节点开始1)
     */
    public static void listChildNodes(Node node, int level) {
        //只处理ElementNode类型的节点
        if(level==0){
            System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ");
        }
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            boolean hasTextChild = false;
            String levelSpace = "";
            for (int i = 0; i < level; i++) {
                levelSpace += "    ";
            }
            //先打印ElementNode的开始标签
            System.out.print(levelSpace + "<" + node.getNodeName()
                    + (node.hasAttributes() ? " " : ">"));// 有属性的话节点的开始标签后面的尖括号">"就留待属性打印完再打印
            if (node.hasAttributes()) {// 遍历打印节点的所有属性
                NamedNodeMap namedNodeMap = node.getAttributes();
                for (int i = 0; i < namedNodeMap.getLength(); i++) {
                    System.out.print(namedNodeMap.item(i).getNodeName()
                            + "=\""// 字符串里含双引号要用到转义字符\
                            + namedNodeMap.item(i).getNodeValue() + "\""
                            + (i == (namedNodeMap.getLength() - 1) ? "" : " "));// 不是最后一个属性的话属性之间要留空隙
                }
                System.out.print(">");// 开始标签里的属性全部打印完加上尖括号">"
            }
            // 该ElementNode包含子节点时候的处理
            if (node.hasChildNodes()) {
                level++;// 有下一级子节点,层次加1,新的层次表示的是这个子节点的层次(递归调用时传给了它)
                // 获得所有的子节点列表
                NodeList nodelist = node.getChildNodes();
                // 循环遍历取到所有的子节点
                for (int i = 0; i < nodelist.getLength(); i++) {
                    //子节点为TextNode类型,并且包含的文本内容有效
                    if (nodelist.item(i).getNodeType() == Node.TEXT_NODE
                            && (!nodelist.item(i).getTextContent().matches("\\s+"))) {// 用正则选取内容包含非空格的有效字符的文本节点
                        hasTextChild = true;// 该ElementNode的一级子节点是存在有效字符的文本节点
                        System.out.print(nodelist.item(i).getTextContent());// 在开始标签后面添加文本内容
                        //子节点是正常的ElementNode的处理
                    } else if (nodelist.item(i).getNodeType() == Node.ELEMENT_NODE) {
                        System.out.println();
                        // 递归调用方法 - 以遍历该节点下面所有的子节点
                        listChildNodes(nodelist.item(i), level);// level表示该节点处于第几个层次(相应空格)
                    }
                }
                level--;// 遍历完所有的子节点,层次变量随子节点的层数,依次递减,回归到该节点本身的层次
                // level++ 和 level--对于该节点的子节点影响的是子节点的初值
            }
            //打印元素的结束标签.如果它的第一个一级子节点是有效文本的话,文本和结束标签添加到开始标签后面,
            //层次什么的就作废用不上了,否则,才按层次打印结束标签.
            System.out.print(((hasTextChild) ? "" : "\n" + levelSpace) + "</"+ node.getNodeName() + ">");
        }
    }
}

4.大功告成,这就是通过DOM方式实现了XML文件的解析,需要注意的地方就是那个递归调用函数,这个事实现动态解析的关键。用过知道了XML文件的内容,可以讲解析出来的具体对象封装起来,以便入库或者其他用处。有机会好好分享下。

时间: 2024-07-30 13:32:09

XML文件解析之DOM解析的相关文章

【Android进阶】解析XML文件之使用DOM解析器

在前面的文章中,介绍了使用SAX解析器对XML文件进行解析,SAX解析器的优点就是占用内存小.这篇文章主要介绍使用DOM解析器对XML文件进行解析.DOM解析器的优点可能是理解起来比较的直观,当然,每个人对不同的解析方法可能有不同的喜好.但是DOM解析器有个比较大的缺点,就是占用内存比较多,在Android中的XML解析中,还是更推荐其他的解析方式. 下面介绍使用DOM解析器对XML进行解析. 下面是我们需要解析的xml文件 <?xml version="1.0" encodin

Java:简单的解析XML文件之使用DOM解析

XML简介 要理解XML,HTML等格式,先来理解文档对象模型DOM 根据 DOM,HTML 文档中的每个成分都是一个节点,这些节点组成了一棵树.DOM 是这样规定的:整个文档是一个文档节点每个 HTML 标签是一个元素节点包含在 HTML 元素中的文本是文本节点每一个 HTML 属性是一个属性节点注释属于注释节点 节点彼此都有等级关系.HTML 文档中的所有节点组成了一个文档树(或节点树).HTML 文档中的每个元素.属性.文本等都代表着树中的一个节点.树起始于文档节点,并由此继续伸出枝条,直

使用JAXP对XML文档进行DOM解析

一.XML解析方式分为两种:dom和sax dom:(Document Object Model,即文档对象模型)是W3C组织推荐的解析XML的一种方式. sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有的XML解析器都支持它. dom和sax解析方法的区别: dom:对文档CRUD(增删改查)比较方便,缺点:占用内存比较大(将xml文件全部读入内存). sax:占用内存较少,解析速度快(从上往下读一行解析一行).缺点:只适合读取,不适合CRU

XML解析之DOM解析技术案例

Java代码: package com.xushouwei.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.No

Java学习总结(21)——XML文档解析:DOM解析,SAX解析

一.XML简介1.可扩展性标记语言(eXtensible Markup Language)2.XML用于描述数据3.应用场合:(1)持久化存储数据(2)数据交换(3)数据配置4.XML语法(1)文档类型:在编写XML文档时,需要先使用文档声明,声明XML文档的类型.最简单的声明语法:<?Xml version="1.0" ?>用encoding属性说明文档的字符编码:<?Xml version="1.0" encoding="GB2312

Java---XML的解析(1)-DOM解析

本章只讲DOM解析.接下来还会学习Dom4j和StAX 解析技术 DOM解析: DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档: <user> <name>Jack</name> <age>30</age> </user> 由于DOM解析,一次性的将所有元素(包含属性和文本) 全部加载到内存中,所以不适用于解析大量的数据. JAXP-DOM解析: 包: javax.xml.parse – 关键类DocumentBuil

Java是如何解析xml文件的(DOM)

Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX DOM4J JDOM (其中DOM.SAX是官方提供的解析方式,不需要额外的jar包,后两种则需要) 例:DOM方式解析books.xml文件 <?xml version="1.0" encoding="UTF-8" ?> <bookstore>

02-Java是如何解析xml文件的(DOM)

Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX DOM4J JDOM (其中DOM.SAX是官方提供的解析方式,不需要额外的jar包,后两种则需要) 例:DOM方式解析books.xml文件 <?xml version="1.0" encoding="UTF-8" ?> <bookstore>

xml解析之----DOM解析

DOM模型(documentobject model) ?DOM解析器在解析XML文档时,会把文档中的全部元素.依照其出现的层次关系.解析成一个个Node对象(节点). ?在dom中.节点之间关系例如以下: ?位于一个节点之上的节点是该节点的父节点(parent) ?一个节点之下的节点是该节点的子节点(children) ?同一层次,具有同样父节点的节点是兄弟节点(sibling) ?一个节点的下一个层次的节点集合是节点后代(descendant) 父.祖父节点 lNode对象提供了一系列常量来