如何动态可配置解析XML
·
实现目标可以根据参数动态解析xml,解析样例文件如下
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book id="SN9787302575443">
<title>Java2实用教程(第6版)</title>
<author>耿祥义、张跃平</author>
<publisher>清华大学出版社</publisher>
<publicationDate>2019-01-01</publicationDate>
<prices>
<price currency="CNY">65</price>
<price currency="MY">9.9</price>
</prices>
<genre>计算机编程</genre>
<description>Java语言的入门教程</description>
</book>
<book id="SN9787020122172">
<title>骆驼祥子</title>
<author>老舍</author>
<publisher>人民文学出版社</publisher>
<publicationDate>1936-01-01</publicationDate>
<prices>
<price currency="CNY">49</price>
<price currency="MY">8.2</price>
</prices>
<genre>文学小说</genre>
<description>描述北平人力车夫的悲剧故事</description>
</book>
</library>
代码实现(输入参数)
{
elementXpath: "/library/book",
fields: [
{
fieldName: "id",
xpath: "/",
type: "attribute",
attrName: "id"
},
{
fieldName: "title",
xpath: 'title',
type: "content",
attrName: ''
},
{
fieldName: "author",
xpath: "author",
type: "content",
attrName: ""
},
{
fieldName: "publisher",
xpath: "publisher",
type: "content",
attrName: ""
},
{
fieldName: "publicationDate",
xpath: "publicationDate",
type: "content",
attrName: ""
},
{
fieldName: "price",
xpath: "prices/price",
type: "content",
attrName: "",
conditionList: [
{
attrName: "currency",
attrValue: "CNY"
}
]
}
]
}
参数说明:
elementXpath 需要解析的元素对象的路径
fields 需要解析元素属性集合
fieldName:解析字段英文名称 必填
xpath:解析字段的路径 必填
type:解析字段类型 attribute | content ( attribute 表示要取属性的值,content 表示要取内容 值)必填
attrName:解析字段属性值(当type =attribute 这里必填)非必填
conditionList:条件集合 attrName=‘attrValue’ 表示匹配到 非必填
定义字段条件解析类
import lombok.Data;
@Data
public class FieldCondition {
private String attrName;
private String attrValue;
}
定义字段解析类
import java.util.List;
@Data
public class FieldXmlNode {
private String fieldName;
private String xpath;
private String type;
private String attrName;
private List<FieldCondition> conditionList;
}
定义解析参数类
import lombok.Data;
import javax.xml.namespace.NamespaceContext;
import java.util.List;
@Data
public class XmlParseParams {
/**
* 元素节点
*/
private String elementXpath;
/**
* 分割符
*/
private String delimiter;
/**
* 字段
*/
private List<FieldXmlNode> fields;
private NamespaceContext nsContext;
}
定义解析类
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.core.util.XmlUtil.UniversalNamespaceCache;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPathConstants;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class XmlParseUtil {
/**
* 解析 xml
*
* @param filePath
* @param params
* @return
*/
public static List<String> xmlParse(String filePath, XmlParseParams params) {
Document document;
try {
FileInputStream inptut = new FileInputStream(filePath);
document = XmlUtil.readXML(new FileInputStream(filePath));
inptut.close();
return xmlParse(document, params);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 解析 xml
*
* @param input
* @param params
* @return
*/
public static List<String> xmlParse(FileInputStream input, XmlParseParams params) {
Document document = XmlUtil.readXML(input);
List<String> result = xmlParse(document, params);
try {
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public static List<String> xmlParse(Document document, XmlParseParams params) {
List<String> result = new ArrayList<String>();
try {
NodeList nodeList = XmlUtil.getNodeListByXPath(params.getElementXpath(), document);// 找到对应路径的所有节点
NamespaceContext nsContext = new UniversalNamespaceCache((Node) document, false);
params.setNsContext(nsContext);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
String res = getFieldValue(node, params);
result.add(res);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static String getFieldValue(Node node, XmlParseParams params) {
StringBuilder stringBuilder = new StringBuilder();
int len = params.getFields().size();
for (FieldXmlNode field : params.getFields()) {
String res = getFieldValue(params, field, node);
stringBuilder.append(res);
if (len > 1) {
stringBuilder.append(params.getDelimiter());
}
len--;
}
return stringBuilder.toString();
}
private static String getFieldValue(XmlParseParams params, FieldXmlNode field, Node node) {
String reuslt = StrUtil.EMPTY;
if (StrUtil.isEmpty(field.getXpath()) || "/".equals(field.getXpath())) {
if (StrUtil.isNotEmpty(field.getType()) && field.getType().toLowerCase().trim().equals("attribute")) {
reuslt = getValueFromElementAttr(node, field);
} else {
reuslt = node.getTextContent();
}
} else {
NodeList nodeList = (NodeList) XmlUtil.getByXPath(field.getXpath(), node, XPathConstants.NODESET, params.getNsContext());
for (int i = 0; i < nodeList.getLength(); i++) {
Node item = nodeList.item(i);
boolean isOk = true;
if (field.getConditionList() != null && field.getConditionList().size() > 0) {
isOk = checkConditon(item, field.getConditionList());
}
if (isOk) {
if (StrUtil.isNotEmpty(field.getType()) && field.getType().toLowerCase().trim().equals("attribute")) {
reuslt = getValueFromElementAttr(item, field);
} else {
reuslt = item.getTextContent();
}
}
}
}
return reuslt;
}
/**
* 取子元素属性满足特定条件的内容进行赋值
*
* @param node
* @param field
* @return
*/
protected static String getValueFromElementAttr(Node node, FieldXmlNode field) {
String result = StrUtil.EMPTY;
try {
String attrName = field.getAttrName();
if (node.getAttributes().getNamedItem(attrName) != null) {
result = node.getAttributes().getNamedItem(attrName).getNodeValue();
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 检测节点
*
* @param nodeElement
* @param conditionList
* @param <T>
* @return
*/
private static <T> boolean checkConditon(Node nodeElement, List<FieldCondition> conditionList) {
boolean res = true;
for (int i = 0; i < conditionList.size(); i++) {
String attrName = conditionList.get(i).getAttrName();
String value = conditionList.get(i).getAttrValue();
if (nodeElement.getAttributes().getNamedItem(attrName) != null) {
String xmlValue = nodeElement.getAttributes().getNamedItem(attrName).getNodeValue();
if (!value.equals(xmlValue)) {
res = false;
}
} else {
res = false;
}
}
return res;
}
}
测试类
public static void main(String[] args) {
String currentDir = System.getProperty("user.dir");
String filePath = "E:\\trunk\\test2.xml";
String conf = "{\n" +
" elementXpath: \"/library/book\", \n" +
" fields: [\n" +
" {\n" +
" fieldName: \"id\", \n" +
" xpath: \"/\", \n" +
" type: \"attribute\", \n" +
" attrName: \"id\"\n" +
" }, \n" +
" {\n" +
" fieldName: \"title\", \n" +
" xpath: 'title', \n" +
" type: \"content\", \n" +
" attrName: '' \n" +
" }, \n" +
" {\n" +
" fieldName: \"author\", \n" +
" xpath: \"author\", \n" +
" type: \"content\", \n" +
" attrName: \"\"\n" +
" }, \n" +
"\t\t{\n" +
" fieldName: \"publisher\", \n" +
" xpath: \"publisher\", \n" +
" type: \"content\", \n" +
" attrName: \"\"\n" +
" }, \n" +
"\t\t{\n" +
" fieldName: \"publicationDate\", \n" +
" xpath: \"publicationDate\", \n" +
" type: \"content\", \n" +
" attrName: \"\"\n" +
" }, \n" +
" {\n" +
" fieldName: \"price\", \n" +
" xpath: \"prices/price\", \n" +
" type: \"content\", \n" +
" attrName: \"\", \n" +
" conditionList: [\n" +
" {\n" +
" attrName: \"currency\", \n" +
" attrValue: \"CNY\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}";
XmlParseParams params = JSONUtil.toBean(conf, XmlParseParams.class);
params.setDelimiter(",");
List<String> list = XmlParseUtil.xmlParse(filePath, params);
for (String item : list) {
System.out.println(item);
}
}
运行结果:

POM 文件 主要引用信息
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.18</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
更多推荐



所有评论(0)