(原创)XML与父子结构树互转

前言

最近在做的一个项目是要做模板化数据的生成,需要做一些数据的标准化,需要对XML文档进行结构化存储,以及从结构化数据转化为XML(freemark模板)

XML转数据库存储

实体类代码

package com.linkjb.fastidious.util;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.dom4j.Attribute;

import java.util.List;

/**
 * @ClassName Node
 * @Description TODO
 * @Author shark
 * @Data 2020/12/2 14:59
 **/
@Data
@TableName(value = "node")
public class Node {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @TableField(value = "name")
    private String name;
    @TableField(value = "value")
    private String value;
    @TableField(value = "attr_list")
    private String attrList;
    @TableField(value = "parent_id")
    private Integer parentId;
    @TableField(exist = false)
    private List<Node> children;

}

业务代码

 @org.junit.Test
    public void main() throws Exception {
        //用自己的方式读取XML文档的模板内容
        String xml ="";
        //解析XML
        SAXReader reader = new SAXReader();
        Document document = reader.read(new ByteArrayInputStream(xml.getBytes()));
        //获取根节点
        Element rootElement = document.getRootElement();
        getNodes(rootElement,null);


    }




/*
    *
     * @Author shark
     * @Description //递归遍历根节点获取存储数据
     * @Date 2020/12/4
     * @Param [node, parentId]
     * @return void
     **/
    public  void getNodes(Element node,Integer parentId){
        System.out.println("--------------------");
        //当前节点的名称、文本内容和属性
        //System.out.println("当前节点Id:"+id);
        Node one = new Node();
        one.setParentId(parentId);
        System.out.println("当前节点名称:"+node.getName());//当前节点名称
        one.setName(node.getName());
        System.out.println("当前节点的内容:"+node.getTextTrim());//当前节点
        one.setValue(node.getTextTrim());
        one.setParentId(parentId);
        List<Attribute> listAttr=node.attributes();//当前节点的所有属性的list
        Map<String,Object> map = new HashMap<>();
        listAttr.forEach(e ->{
            map.put(e.getName(),e.getValue());
        });
        String s = JSON.toJSONString(map);
        one.setAttrList(s);
        //数据库插入操作
        nodeMapper.add(one);
        data.add(one);

        //递归遍历当前节点所有的子节点
        List<Element> listElement=node.elements();//所有一级子节点的list
        for(Element e:listElement){//遍历所有一级子节点
            getNodes(e,one.getId());//递归
        }
    }

数据库数据转XML

    @org.junit.Test
    public void main() throws Exception {
//        //用自己的方式读取XML文档的模板内容
//        String xml ="";
//        //解析XML
//        SAXReader reader = new SAXReader();
//        Document document = reader.read(new ByteArrayInputStream(xml.getBytes()));
//        //获取根节点
//        Element rootElement = document.getRootElement();
//        getNodes(rootElement,null);


        //        getNodes(rootElement,id);// 调用遍历节点的方法,从跟节点遍历

    
        Node tree = getTree();
        String s = generateTree(tree);
        s = XMLUtils.formatXml(s);
        log.info(s);


    }
    public Node getTree() {
        List<Node> root = nodeMapper.selectList(new QueryWrapper<Node>().eq("id",1));
        List<Node> allNodes = nodeMapper.selectByMap(null);
        List<Node> nodes = buildTree(root,allNodes);
        return nodes.get(0);
    }
    private List<Node> buildTree(List<Node> root,List<Node> allNodes) {
        for(int i=0; i < root.size(); i++) {
            //StringUtils.isNotBlank(s.getParentId())
            int finalI = i;
            List<Node> children = allNodes.stream().filter(s -> s.getParentId() != null && s.getParentId().equals(root.get(finalI).getId())).collect(Collectors.toList());
            //List<Node> children = getSonByParentId(root.get(i).getId());
            buildTree(children,allNodes);
            root.get(i).setChildren(children);
        }
        return root;
    }
    public String generateTree(Node node){
        StringBuilder s = new StringBuilder();
        s.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        generate(node, s);
        return s.toString();
    }
    public String generate(Node node,StringBuilder s){

        List<Node> sonByParentId = node.getChildren();
        s.append("<"+node.getName());
        String attrList = node.getAttrList();
        Map<String,Object> map = JSON.parseObject(attrList, Map.class);
        if(!map.isEmpty()){
            StringBuilder append  = new StringBuilder();
            for(Map.Entry<String,Object> entry : map.entrySet()){
                append.append(" "+entry.getKey()+"="+"\""+entry.getValue()+"\" ");
            }
            String substring = append.substring(0, append.length() - 1);
            s.append(substring);
        }
        if(sonByParentId.size()>0){
            s.append(">");
            //有子节点说明肯定无值
            for (Node sonNode:sonByParentId){
                generate(sonNode,s);
            }
            s.append("</"+node.getName()+">");

        }else{
            //无子节点
            if(node.getValue()==null||"".equals(node.getValue())){
                //无值
                s.append("/>");
            }else{
                s.append(">"+node.getValue()+"</"+node.getName()+">");
            }

        }
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;


/**
 * @ClassName XMLUtils
 * @Description TODO
 * @Author shark
 * @Data 2020/12/3 16:00
 **/
public class XMLUtils {
   public static String formatXml(String str) throws DocumentException, IOException {
       Document document = null;
       document = DocumentHelper.parseText(str);
       OutputFormat format = OutputFormat.createPrettyPrint();
       format.setEncoding("UTF-8");
       StringWriter writer = new StringWriter();
       XMLWriter xmlWriter = new XMLWriter(writer, format);

       xmlWriter.write(document);
       xmlWriter.close();
       return writer.toString();

   }
}

标题:(原创)XML与父子结构树互转
作者:sharkshen@outlook.com
地址:HTTPS://www.linkjb.com/articles/2020/12/03/1606989728537.html

    评论
    0 评论
avatar

取消