Dom和xpath解析xml文件

本文介绍MyBatis在初始化过程中如何使用DOM和XPath解析mybatis-config.xml及映射文件,通过示例展示了如何利用XPath查询XML文档中的特定节点,包括按作者筛选图书标题和按年份筛选图书。

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

Mybatis在初始化过程中处理mybatis-config.xml文件以及映射文件时,采用DOM进行解析,并结合使用XPATH解析XML配置文件。如果对前端熟悉的伙伴,应该了解前端的DOM树,这里也一样,DOM会将整个xml文件加入内存中并形成一个树状数据结构,而XPath是一种为查询XML文档而设计的语言(对Python爬虫了解的话,用xpath来选节点),可以与DOM解析方式配合使用,实现对XML文档的解析。

XPath使用路径表达式来选取XML文档中指定的节点或者节点集合,与常见的URL路径有些类似。XML中常用的表达式:

下面就开始来看看示例吧:

建立一个java项目:

目录结构如下:

inventory.xml文件的内容如下:

<inventory>
    <book year="2018">
        <title>Show Crash</title>
        <author>Neal Stephenson</author>
        <publisher>Spectra</publisher>
        <isbn>242432</isbn>
        <price>14.23</price>
    </book>
    <book year="2008">
        <title>Burning Tower</title>
        <author>Larry Niven</author>
        <author>Jerry Pournelle</author>
        <publisher>Pocket</publisher>
        <isbn>3533134299</isbn>
        <price>13.67</price>
    </book>

    <book year="1993">
        <title>Zodiac</title>
        <author>Neal Stephenson</author>
        <publisher>Spectra</publisher>
        <isbn>3533923842</isbn>
        <price>7.55</price>
    </book>
</inventory>

然后是测试文件的内容:

package mybatis.domXpath;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;

public class XpathTest {
    public static void main(String[] args) throws ParserConfigurationException, 
                        IOException, SAXException, XPathExpressionException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        // 开启验证
        documentBuilderFactory.setValidating(true);
        documentBuilderFactory.setNamespaceAware(false);
        documentBuilderFactory.setIgnoringComments(true);
        documentBuilderFactory.setIgnoringElementContentWhitespace(false);
        documentBuilderFactory.setCoalescing(false);
        documentBuilderFactory.setExpandEntityReferences(true);

        // 创建DocumentBuilder
        DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
        // 设置异常处理对象
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException exception) throws SAXException {
                System.out.println("error:"+exception.getMessage());
            }
            @Override
            public void error(SAXParseException exception) throws SAXException {
                System.out.println("fatalError"+exception.getMessage());
            }
            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                System.out.println("warn"+exception.getMessage());
            }
        });
        // 将文档加载到一个Document对象中
        Document doc = builder.parse("source/inventory.xml");
        
        // 创建XpathFactory
        XPathFactory factory = XPathFactory.newInstance();
        // 创建xpath对象
        XPath xpath = factory.newXPath();
        // 编译XPath表达式
        XPathExpression compile = ((XPath) xpath).compile(
                        "/book[author='Neal Stephenson']/title/text()");

        // 通过xpath表达式得到的结果,第一个参数制定了XPath表达式进行查询的上下文节点,
        // 也就是在指定节点下查找符合xpath的节点。本示例中的上下文节点是整个文档;
        // 第二个参数制定了xpath表达式的返回类型。
        Object result = compile.evaluate(doc, XPathConstants.NODESET);
        System.out.println("查询作为为Neal Stephenson的图书标题是:");
        NodeList nodes = (NodeList)result;
        for (int i = 0; i < nodes.getLength(); i++) {
            System.out.println(nodes.item(i).getNodeValue());
        }

        System.out.println("查询1997年之后的图书标题:");
        nodes = (NodeList)xpath.evaluate(
                    "//book[@year>1997]/title/text()",doc,XPathConstants.NODESET);
        for (int j = 0; j < nodes.getLength(); j++) {
            System.out.println(nodes.item(j).getNodeValue());
        }

        System.out.println("查询1997年之后的图书属性和标题:");
        nodes = (NodeList)xpath.evaluate(
                "//book[@year>1997]/@*|//book[@year>1997]/title/text()"
                ,doc,XPathConstants.NODESET);
        for (int i = 0; i < nodes.getLength(); i++) {
            System.out.println(nodes.item(i).getNodeValue());
        }
    }
}

执行结果如下:

fatalError文档根元素 "inventory" 必须匹配 DOCTYPE 根 "null"。
fatalError文档无效: 找不到语法。
查询作为为Neal Stephenson的图书标题是:
查询1997年之后的图书标题:
Show Crash
Burning Tower
查询1997年之后的图书属性和标题:
2018
Show Crash
2008
Burning Tower

嗯。。。有一些错误,,,我没去找了,暂时够用,对不起了。

 

示例来源:《MyBatis技术》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值