实现目标可以根据参数动态解析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>

      

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐