场景:今天做项目的时候遇到解析xml,见到了公司项目中用到了Xpath,感觉很新鲜记录一下(公司项目代码如下)。
String fileName = displayText;
int ext = displayText.indexOf(".");
Document datumInfo = amService.getDatumTree(bizDefGuid, bizInstGuid,category, recordNumber);
//String datumTrese1 =datumInfo.asXML();
String title = fileName.substring(0, ext);
String xpath = String.format(".//Datum/Page/ImageDesc[text()='%s']",title);
List<Node> nodes = datumInfo.selectNodes(xpath);
公司需求:上传文件名称不能重复,文件上传后在档案系统记录如下(我需要做的是判断如下的xml中是否存在<ImageDesc>电子政务中台</ImageDesc>存在个数大于1即可)
<?xml version="1.0" encoding="UTF-8"?>
<Response><status>0</status>
<TreeRoot><EntryId>33824</EntryId>
<Datum>
<DatumId>74718</DatumId>
<DatumName><![CDATA[新建资料ss]]></DatumName>
<Page>
<PageId>2740</PageId>
<Number>1</Number>
<Extension>DOCX</Extension>
<ImageDesc>电子政务中台</ImageDesc>
</Page>
<Page>
<PageId>2741</PageId
<Number>2</Number>
<Extension>DOCX</Extension>
<ImageDesc>电子政务中台</ImageDesc>
</Page>
</Datum>
</TreeRoot>
</Response>
什么是Xpath
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。
解析xml过程分析
Document datumInfo = amService.getDatumTree(bizDefGuid, bizInstGuid,category, recordNumber);
源码解析:
public static Document parseText(String text) throws DocumentException {
Document result = null;
SAXReader reader = new SAXReader();
String encoding = getEncoding(text);
InputSource source = new InputSource(new StringReader(text));
source.setEncoding(encoding);
result = reader.read(source);
// if the XML parser doesn't provide a way to retrieve the encoding,
// specify it manually
if (result.getXMLEncoding() == null) {
result.setXMLEncoding(encoding);
}
return result;
}
通过DocumentHelper工具类中(package org.dom4j包中)parseText中通过SAXReader reader = new SAXReader() 对象中read方法读取xml字符串输入流。
Document和Node节点的继承关系如下:
public interface Document extends Branch
public interface Branch extends Node
Node接口中两个重要的方法
/**
* <p>
* <code>selectNodes</code> evaluates an XPath expression and returns the
* result as a <code>List</code> of <code>Node</code> instances or
* <code>String</code> instances depending on the XPath expression.
* </p>
*
* @param xpathExpression
* is the XPath expression to be evaluated
*
* @return the list of <code>Node</code> or <code>String</code>
* instances depending on the XPath expression
*/
List selectNodes(String xpathExpression);
通过xpathExpression表达式获取Node节点集合(多个NODE)
/**
* <p>
* <code>selectSingleNode</code> evaluates an XPath expression and returns
* the result as a single <code>Node</code> instance.
* </p>
*
* @param xpathExpression
* is the XPath expression to be evaluated
*
* @return the <code>Node</code> matching the XPath expression
*/
Node selectSingleNode(String xpathExpression);
通过xpathExpression表达式获取Node节点对象(单个NODE)
基本表达式
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
具体实例
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
the XPath expression (.//Datum/Page/ImageDesc)表示从当前节点Datum中选取所有Page节点中的ImageDesc节点且匹配ImageDesc节点中文本值是title的节点
String.format(".//Datum/Page/ImageDesc[text()='%s']",title);
具体参考如下(照葫芦画瓢就中):
参考:
W3School网:https://www.w3school.com.cn/xpath/index.asp
博主一:https://blog.csdn.net/adawyy/article/details/83212638
博主二:https://www.cnblogs.com/unknows/p/7684331.html