XML学习---XML文档解析

本文介绍Java中解析XML文档的方法,包括DOM、SAX、Dom4j及StAX等技术,并详细展示了DOM解析的具体实现步骤与代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java对XML文档进行解析

解析XML的几种方式的概述;
这里写图片描述

JAXP(JavaApi for Xml Programming) – sun公司的一套操作XML的API.

  • DOM解析-一次性的将数据全部装入内存。
  • SAX解析-边读取边解析

Dom4j(Document For Java)-第三方开源,是从jdom分裂出来的解析技术。目前jdom已经完全被dom4j替代。

  • jDom – Dom4j的前身。
  • Dom4j在性能和速度上都比sun公司的要快,而且支持Xpath快速查找,目前像Spring,Hibernate这些大型的框架,都是用的dom4j.

StAX – JDK1.6新特性,做为JAXP的新成员已经集成在了JDK6当中

DOM解析学习实例:
主要用来解析下面这个文档:

<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="A001">
    <name>Jack</name>
    <age>22</age>
  </user>
  <user id="A002">
    <name>张三</name>
    <age>24</age>
  </user>
</users>

第一步:是获取DOM 对象。 (w3c的document)

// w3c仅仅提供标准、java 提供创建方法
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("./xml/users.xml");

第二部:获取DOM下面的节点:

Node root = dom.getFirstChild();
System.out.println("NodeName:"+root.getNodeName());
System.out.println("---------------------");

演示结果:成功拿到users节点
这里写图片描述

看看他有哪些子节点: 应该是 两个 user 才对

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new File("./xml/users.xml"));

Node root = dom.getFirstChild();
System.out.println("NodeName:"+root.getNodeName());
System.out.println("---------------------");
NodeList list = root.getChildNodes();
for(int i=0;i<list.getLength();i++){
    System.out.println(list.item(i).getNodeName());
}

演示结果: 换行符也是子节点!!!
这里写图片描述

接下来拿name标签的值
方式一:通过孩子节点

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new File("./xml/users.xml"));

Node root = dom.getFirstChild();
System.out.println("NodeName:"+root.getNodeName());
System.out.println("---------------------");
NodeList list = root.getChildNodes();
for(int i=0;i<list.getLength();i++){
    System.out.println(list.item(i).getNodeName());
}
System.out.println("---------------------");
//不建议采用的方式(理由见后面的讲解)---Node.getChildNodes()
NodeList nodeList = root.getChildNodes();
System.out.println("节点数:"+nodeList.getLength());
Node node = nodeList.item(1);
System.out.println("NodeName:"+node.getNodeName());
Node nameNode = node.getChildNodes().item(1);
String name = nameNode.getTextContent();
System.out.println("name="+name);

演示结果:
这里写图片描述

方式二:通过标签明

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document dom = db.parse(new File("./xml/users.xml"));

    Node root = dom.getFirstChild();
    System.out.println("NodeName:"+root.getNodeName());
    System.out.println("---------------------");

    //采用建议的方式---Element中的getElementsByTagName(String name)
    //为了使用Element中的方法,必须得强转成Element类型
    Element eRoot = (Element)root;
    NodeList userList= eRoot.getElementsByTagName("user");
    Element eUser1 = (Element) userList.item(0);
    NodeList nameList = eUser1.getElementsByTagName("name");
    Node nameNode = nameList.item(0);
    String name = nameNode.getTextContent();
    System.out.println(name);

演示结果:
这里写图片描述

同样的也可以拿到年龄

DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document dom = db.parse(“./xml/users.xml”);
Element root = (Element) dom.getFirstChild();
Element eUser = (Element) root.getElementsByTagName(“user”).item(1);
Node eName=eUser.getElementsByTagName(“age”).item(0);
String strAge = eName.getTextContent();
System.out.println(“age=”+strAge);

演示结果:
这里写图片描述

整片学习代码:

package cn.hncu.jaxp.dom;

import java.io.File;

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

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
 * JDK中有两个专用于进行dom编程的包:
 * 1) org.w3c.dom  ----w3c是制定标准
 * 2) javax.xml.parsers ----sun公司开发出来给我们解析用的
 * 
 * 
 * 入口: Document接口(来自w3c,org.w3c.dom包)   --> 要用工厂方法获得该dom对象 ---工厂方法来自sun公司(javax.xml.parsers包)
 * 
 */
public class DomDemo {
    @Test
    public void getDom() throws Exception{
        //获取dom对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document dom = db.parse("./xml/users.xml");
        System.out.println(dom);
    }


    //需求:读取第一个<user>节点中的<name>值
    @Test
    public void getName() throws Exception{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document dom = db.parse(new File("./xml/users.xml"));

        Node root = dom.getFirstChild();
        System.out.println("NodeName:"+root.getNodeName());
        System.out.println("---------------------");

        //不建议采用的方式(理由见后面的讲解)---Node.getChildNodes()
        NodeList nodeList = root.getChildNodes();
        System.out.println("节点数:"+nodeList.getLength());
        Node node = nodeList.item(1);
        System.out.println("NodeName:"+node.getNodeName());
        Node nameNode = node.getChildNodes().item(1);
        String name = nameNode.getTextContent();
        System.out.println("name="+name);
    }

    /*
     * 以后要遍历文档,最好的选择方式是:
     *   采用Element中的getElementsByTagName(String name),
     *   返回类型为:NodeList, 获取当前元素下面的所有对应标签的那些子元素(
     *   仅仅是标签节点---能够去除文本内容尤其是空白符的干扰)。
     * 
     * 建议不要采用如下两种方式:
     * 1)通过Node中的 getChildNodes(),返回类型为:NodeList, 获取当前节点的所有
     * 子节点(包括文本内容和标签节点)----不选择的理由:文本内容尤其是空白符也是其中的孩子节点,会产生干扰
     * 2)通过Document的getElementById(String elementId), 返回Element节点,
     * 这种方式在browse-dom中用起来是非常方便的,但在Java-dom中必须得给
     * DocumentBuilderFactory对象设置schema
     * 
     */

    //需求:读取第一个<user>节点中的<name>值
        @Test  //OOOOOOKKKKKK
        public void getName2() throws Exception{
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document dom = db.parse(new File("./xml/users.xml"));

            Node root = dom.getFirstChild();
            System.out.println("NodeName:"+root.getNodeName());
            System.out.println("---------------------");

            //采用建议的方式---Element中的getElementsByTagName(String name)
            //为了使用Element中的方法,必须得强转成Element类型
            Element eRoot = (Element)root;
            NodeList userList= eRoot.getElementsByTagName("user");
            Element eUser1 = (Element) userList.item(0);
            NodeList nameList = eUser1.getElementsByTagName("name");
            Node nameNode = nameList.item(0);
            String name = nameNode.getTextContent();
            System.out.println(name);
        }

        //需求:读取第二个<user>节点中的<age>值
        @Test  //OOOOOOKKKKKK
        public void getAge() throws Exception{
            DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document dom = db.parse("./xml/users.xml");
            Element root = (Element) dom.getFirstChild();
            Element eUser = (Element) root.getElementsByTagName("user").item(1);
            Node eName=eUser.getElementsByTagName("age").item(0);
            String strAge = eName.getTextContent();
            System.out.println("age="+strAge);
        }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值