(原创)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