【XML】DOM—JAXP 解析

本文介绍了文档对象模型(DOM)解析器的基本概念及其在Java中的应用。解析了DOM规范的节点类型与常用接口,并通过示例代码展示了如何使用DOM解析器读取XML文件,构建Document对象并从中提取数据。

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

1. DOM 解析器

文档对象模型(Document Object Model),规定了解析文档的接口,各种语言都可以按照DOM规范去实现这些接口,DOM规范可以解析的文档和广泛,包括XML文件和HTML文件。

语言绑定:在特定语言中,使用DOM规范需要定义DOM规范制定的接口,并给出实现接口的类的集合。Sun公司提供了JAXP,实现了DOM规范的Java语言绑定。

2. DOM API

2.1 DOM文档节点类型

DOM解析器调用parse方法返回一个Document对象,它是由实现了Node接口的实例组成的树状结构数据

2.2 Node常用接口

  • Attr:节点属性
  • CDATASection:转义文本块
  • Document
  • DobumentType
  • Element
  • Test

2.3 DOM 文档节点常用方法

  • getNodeType(): short
  • getChildNodes(): NodeList
  • getFirstChild(): Node
  • getLastChild(): Node
  • getNodeName(): String
  • getTextContet(): NodeList
  • getAttributes(): NamedNodeMap

文档节点嵌套关系
这里写图片描述

3. DOM vs SAX

SAX解析的代码重点是构建事件处理程序
这里写图片描述
SAX的解析方法是SAXParse中的parse(arg1,arg2)方法。

arg1通常是传入文件输入流,arg2是定义的事件处理程序。

也就是说SAX的解析过程是基于输入流的。以便读入XML文档信息,一遍通过事件触发规则进行处理。


DOM解析的代码重点是对Document树状结构中元素的遍历
这里写图片描述
DOM的解析方法是DocumentBuilder中的parse(File)方法。

首先将XML读入基于Node树形结构的文档中,在通过条件逻辑对Node元素进行处理。

也就是说DOM解析过程是基于Document文档的,首先将XML整体放入内存的节点树结构Document,Dobument作为中介,实现从XML文件到Java对象实例化的工作。

4. 解析流程:

  1. 创建DocumentBuilderFactory工厂类对象factory。
  2. 通过工厂对象创建DocumentBuilder类的实例对象builder。
  3. 用builder的parse方法,将XML文档结构化为Dobument。

SAP Parser
这里写图片描述

DOM Parser
这里写图片描述

从类图结构上看,DOM的构建逻辑要比SAX简单。

代码示例:

package xmlDOMDemo;

import java.util.List;

import xmlSAXDemo.Book;

public interface XmlParse {
    //从指定的XML文件中返回书的列表
    public List<Book> parseXml(String fileName);
}
package xmlDOMDemo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

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

import xmlSAXDemo.Book;
import xmlSAXDemo.XmlParse;

public class MyDomParser implements XmlParse{


    public List<Book> parseXml(String fileName){

        List<Book> bookList=new ArrayList<Book>();
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        Document document=null;
        try {
            DocumentBuilder builder=factory.newDocumentBuilder();
            document=builder.parse(new File(fileName));
        } 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();
        }

//      根节点的所有孩子是我们要遍历的元素,赋值给book元素
        Node rootNode=document.getDocumentElement();
        NodeList nodeElementList=rootNode.getChildNodes();
//      遍历树形结构的每一个节点元素
        for(int i=0;i<nodeElementList.getLength();i++){
            Node nodeElement=nodeElementList.item(i);
            if(nodeElement.getNodeName()=="book"){
//              创建Book对象,将从Document中取出的元素信息添加到Book对象中
                Book book=new Book();
//              树形结构的元素通过getAttibutes方法得到名-值对的Map列表
                NamedNodeMap map=nodeElement.getAttributes();
//              通过名称得到对应的Node对象,这里Node已经不是我们从Document中取出来的Element了
                Node bookNoNode=map.getNamedItem("bookNo");
                String bookNoValue=bookNoNode.getNodeValue();
//              给book对象的bookNo赋值
                book.setBookNo(bookNoValue.trim());

                //元素的所有孩子节点使我们要遍历的子元素,赋值给book元素的子元素
                NodeList subElementList=nodeElement.getChildNodes();
//              遍历每一个节点元素的子元素
                for(int j=0;j<subElementList.getLength();j++){
                    Node subElement=subElementList.item(i);
                    String subElementName=subElement.getNodeName();
//                  对不同的子元素赋值
                    switch(subElementName)
                    {
                        case "title":
                            book.setTitle(subElement.getTextContent().trim());
                        case "author":
                            book.setAuther(subElement.getTextContent().trim());
                        case "price" :
                            book.setPrice(Double.parseDouble(subElement.getTextContent().trim()));
                    }
                }
                //遍历完每个元素的子元素,就完成了一个book对象的赋值,把book添加到bookList
                bookList.add(book);
            }
        }

        return null;

    }
    public static void main(String[] args) {

        XmlParse parser=new MyDomParser();
        List<Book> list=parser.parseXml("bookStore.xml");

        for(Book book:list){
        System.out.println(book.toString());

        }
    }
}
//从BookStore.xml解析得到的信息会创建成本类的实例对象。
public class Book {
    private String bookNo;
    private String title;
    private String auther;
    private double price;
    @Override
    public String toString() {
        return "Book [bookNo=" + bookNo + ", title=" + title + ", auther="
                + auther + ", price=" + price + "]";
    }

    public Book() {
        super();
    }

    public Book(String bookNo, String title, String auther, double price) {
        super();
        this.bookNo = bookNo;
        this.title = title;
        this.auther = auther;
        this.price = price;
    }

    public String getBookNo() {
        return bookNo;
    }

    public void setBookNo(String bookNo) {
        this.bookNo = bookNo;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuther() {
        return auther;
    }

    public void setAuther(String auther) {
        this.auther = auther;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值