XPathParser类是mybatis对 javax.xml.xpath.XPath的包装类。
接下来我们来看下XPathParser类的结构
1、属性
// 存放读取到的整个XML文档
private final Document document;
// 是否开启验证
private boolean validation;
// 自定义的DTD约束文件实体解析器,与validation配合使用
private EntityResolver entityResolver;
// MyBatis配置文件中的properties节点的信息
private Properties variables;
// XPath工具
private XPath xpath;
2、构造函数
public XPathParser(String xml) {
commonConstructor(false, null, null);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
构造方法包含两部分:
- 初始化属性
private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
this.validation = validation;
this.entityResolver = entityResolver;
this.variables = variables;
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}
- 构建XML文档对应的Document
private Document createDocument(InputSource inputSource) {
// important: this must only be called AFTER common constructor
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(validation);
factory.setNamespaceAware(false);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setCoalescing(false);
factory.setExpandEntityReferences(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(entityResolver);
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void warning(SAXParseException exception) throws SAXException {
}
});
return builder.parse(inputSource);
} catch (Exception e) {
throw new BuilderException("Error creating document instance. Cause: " + e, e);
}
}
3、方法
基本类型的解析方法,最终调用的都是方法 evalString(Object root, String expression)
private Properties variables;
private XPath xpath;
public String evalString(Object root, String expression) {
// 解析结果
String result = (String) evaluate(expression, root, XPathConstants.STRING);
// 对${}变量从Properties配置文件中进行查找相应的属性值替换,若variables为空或未查找到${}直接返回result
result = PropertyParser.parse(result, variables);
return result;
}
private Object evaluate(String expression, Object root, QName returnType) {
try {
// 调用XPath进行解析
return xpath.evaluate(expression, root, returnType);
} catch (Exception e) {
throw new BuilderException("Error evaluating XPath. Cause: " + e, e);
}
}
4、总结
可使用XPathParser类来解析自己定义的XML文件,同时也可以仿照mybatis定义自己的Properties文件类替换XML文件中的变量值
String path = "E:\\GitResource\\springboot-bucket\\springboot-mybatis\\src\\main\\resources\\mapper\\20240729.xml";
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(path);
XPathParser xPathParser = new XPathParser(document,false,null,null);
String evalString = xPathParser.evalString("/mapper/sql[1]");
System.out.println(evalString);