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技术》