当前位置: 首页 > news >正文

图形化数据报文转换映射工具

目录

    • 概要
    • 整体架构流程
    • 技术名词解释
    • 技术细节
    • 小结

概要

在当今数字化时代,数据的处理和分析是企业、科研机构以及各类组织日常运营的核心环节。数据来源广泛,格式多样,常见的数据格式包括XML(可扩展标记语言)和JSON(JavaScript对象表示法)。XML以其结构化和可扩展性强的特点,被广泛应用于配置文件、数据交换以及复杂数据结构的描述;而JSON则因其简洁、易读易解析的特性,在Web开发、API接口以及轻量级数据传输中占据重要地位。然而,在实际的数据处理流程中,我们经常会遇到需要将一种数据格式转换为另一种格式的情况,以满足不同系统、平台或应用之间的数据交互需求。

具体来说,常见的数据映射转换需求包括以下几种场景:

  1. XML到XML的转换:当数据在不同的XML系统之间传递时,可能需要对数据结构进行调整或优化,以适配目标系统的XML模式。例如,将一个复杂的企业级配置文件从一种XML格式转换为另一种更简洁或更符合规范的XML格式,以提高系统的兼容性和可维护性。
  2. JSON到JSON的转换:在Web开发和数据处理中,JSON数据结构可能需要根据不同的应用场景进行调整。比如,将一个包含大量嵌套对象和数组的JSON数据重新组织,以便更好地适配前端展示或后端处理逻辑。这种转换可能涉及字段的重命名、数据类型的转换以及数据结构的重组。
  3. XML到JSON的转换:随着Web技术的发展,越来越多的系统倾向于使用JSON作为数据传输格式。因此,当从一个基于XML的旧系统迁移到一个基于JSON的新系统时,就需要将XML数据转换为JSON格式。例如,将一个XML格式的用户配置文件转换为JSON格式,以便在现代的Web应用中使用。
  4. JSON到XML的转换:在某些情况下,尽管JSON是主流的数据格式,但某些系统或平台可能仍然依赖XML。例如,将JSON格式的API响应数据转换为XML格式,以适配遗留系统的数据处理需求。

为了高效、准确地完成这些数据格式的转换和映射,我们需要一个灵活且强大的工具或框架。

通过实现这样一个数据格式转换工具,我们不仅可以提高数据处理的效率,还能确保数据在不同系统之间的顺畅交互,从而为企业的数字化转型和数据驱动的决策提供有力支持。

在当前的数据处理领域,虽然有许多数据映射和转换工具可供选择,但很难找到一款完全符合个性化需求的工具。为此,我们开发了一款基于Java的数据转换映射工具,旨在提供一种直观、高效且易于操作的解决方案。该工具的图形界面基于Swing开发,支持XML和JSON两种常见数据格式的转换。

工具功能特点

  1. 支持多种数据格式
    用户可以选择XML和JSON作为源格式和目标格式,工具支持从XML到XML、XML到JSON、JSON到XML以及JSON到JSON的双向转换。
  2. 树形结构可视化
    数据加载后会以树形格式展示,用户可以清晰地查看数据结构。这种可视化方式使得数据映射过程更加直观。
  3. 拖拽式映射操作
    用户可以通过拖动源树的节点到目标树的节点,形成连线完成数据映射。这种拖拽式操作极大地简化了映射过程,降低了操作难度。
  4. 灵活的映射规则配置
    支持基于规则的映射和条件映射,用户可以根据实际需求自定义映射逻辑。

通过Swing开发的图形界面,用户可以轻松上手操作,无需复杂的配置和编程知识。这种无代码或低代码的映射方式,使得工具不仅适用于开发人员,也适合非技术背景的用户。

整体架构流程

经过长时间的钻研分析相关技术,通过实现可视化界面映射,使用Dom4j和fastjson进行xml和json的数据处理,制定了连线的映射规则,形成了一个能够在xml和json之间任意节点进行映射转换的工具。

实现工具的界面如下:

界面上的菜单中能够选择源和目标,将数据加载成树型。

界面上能够拖拽进行连线映射。

可选择菜单中的保存来保存映射连线

可通过菜单中的执行按钮进行数据映射测试

技术细节

    1. 界面实现

界面采用swing开发,不熟悉swing的同学可先学习一下swing的相关知识。代码较多这里只给出部分关键代码。

主题界面代码如下:

/**

        *

        * 构造函数

        */

       public Transformer() {

              super("数据映射");//标题

              instance = this;

              XMLMapperInit.initLookAndFeel();

              setIconImage(XMLMapperInit.loadIcon(XMLMapperInit.ICON_APP).getImage());

              mapView = new MapView(this);//映射区

              outputXSLT = new JTextArea();

              testMessageView = new XmlPane();

              testMessageView.setContentType("text/xml");

              tabPane = new MyTabbedPane();

              getContentPane().add(tabPane);

              menuBar = new MyMenuBar();//菜单

              setJMenuBar(menuBar);

       }

这里主要看映射区,在这里创建了左右的两棵树,并生成了中间的连线面板来显示连线。

/**

        *

        * 构造函数

        *

        * @param transformer

        *            界面类

        */

       public MapView(Transformer transformer) {

              super(JSplitPane.VERTICAL_SPLIT, true);

              this.transformer = transformer;

              srcTree = new MapperTree(false);

              dstTree = new MapperTree(true);

              /**

               * 设置两棵树的ComponentModel属性,树丛该属性中获得消息格式的值

               *

               * @author mzj

               */

              srcTree.setComponentModel(transformer.getSourceModel());

              dstTree.setComponentModel(transformer.getDestinationModel());

              objectPanel = new ObjectPanel(this, srcTree, dstTree);

              propView = new PropertyPane(this);

              leftPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);

              rightPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);

              srcTree.addTreeSelectionListener(propView);

              dstTree.addTreeSelectionListener(propView);

              leftPane.setBorder(null);

              rightPane.setBorder(null);

              this.setBorder(null);

              // ///

              // Positioning the main components between the splitters

              // ///

              leftPane.setLeftComponent(srcTree.getScrollPane());

              leftPane.setRightComponent(rightPane);

              rightPane.setLeftComponent(objectPanel);

              rightPane.setRightComponent(dstTree.getScrollPane());

              this.setTopComponent(leftPane);

              // this.setBottomComponent(propView);

              leftPane.setDividerSize(2);

              rightPane.setDividerSize(2);

              addComponentListener(new ComponentListener() {

                     public void componentHidden(ComponentEvent e) {

                     }

                     public void componentMoved(ComponentEvent e) {

                     }

                     public void componentResized(ComponentEvent e) {

                            Dimension d = e.getComponent().getSize();

                            setSize(d);

                            int x = getWidth() / 3;

                            rightPane.setDividerLocation(x);

                            leftPane.setDividerLocation(x);

                            MapView.this.setDividerLocation((int) ((getHeight() / 3) * 2));

                     }

                     public void componentShown(ComponentEvent e) {

                     }

              });

       }

    1. 源和目标的数据加载

通过选择文件菜单中的加载源和加载目标进行数据格式加载。相关代码如下:

public void loadOutFileXML(String dirOne) throws DocumentException {

              String messageXml = dirOne;

              if(dirOne.endsWith(".json")) {

                     sourceType=NodeUtil.JSON;

              }else {

                     sourceType=NodeUtil.XML;

              }

              if (messageXml != null && !messageXml.equals("")) {

                     MapperTree.this.load(dirOne);

              }

       }

       public void loadInFileXML(String dirTwo) throws DocumentException {

              String messageXml = dirTwo;

              if(dirTwo.endsWith(".json")) {

                     targetType=NodeUtil.JSON;

              }else {

                     targetType=NodeUtil.XML;

              }

             

              if (messageXml != null && !messageXml.equals("")) {

                     MapperTree.this.load(dirTwo);

              }

       }

将数据加载成MapperTreeModel加载到界面上显示,MapperTreeModel类继承了DefaultTreeModel。

public class MapperTreeModel extends DefaultTreeModel {

       private static final long serialVersionUID = 6124199500486839241L;

       protected boolean bLoaded = false;

       /**

        * @author mzj

        */

       private GeneriqueSpoModel componentModel;

       public MapperTreeModel(MapperTreeNode newRoot) {

              super(newRoot);

       }

       public boolean Load(String filename) {

              return false;

       }

       public boolean isLoaded() {

              return bLoaded;

       }

       /**

        * @param componentModel

        */

       public void setComponentModel(GeneriqueSpoModel componentModel) {

              this.componentModel = componentModel;

       }

       /**

        * @return

        */

       public GeneriqueSpoModel getComponentModel() {

              return componentModel;

       }

}

    1. 映射界面

这里MapperTree继承了JTree实现了可拖拽的树。ObjectPanel实现了JPanel面板。用于绘制拖拽的连线。ObjectPanel实现了画线的事件。

class MyDragSourceListener implements DragSourceListener {

              public void dragDropEnd(DragSourceDropEvent event) {

                     if (event.getDropSuccess()) {

                            repaint(); // 画线

                     }

              }

              public void dragEnter(DragSourceDragEvent event) {

                     DragSourceContext context = event.getDragSourceContext();

                     context.setCursor(DragSource.DefaultLinkDrop);

              }

              public void dragExit(DragSourceEvent event) {

              }

              public void dragOver(DragSourceDragEvent event) {

              }

              public void dropActionChanged(DragSourceDragEvent event) {

              }

       }

      

       class MyDragGestureListener implements DragGestureListener {

              public void dragGestureRecognized(DragGestureEvent event) {

                     Point pt = event.getDragOrigin();

                     IMapObject obj = ObjectPanel.this.getMap().getChildAt(pt);

                     if (obj != null && (obj instanceof ILinkable)) {

                            ILinkable src = (ILinkable) obj;

                            if (src.willAccept(null)) {

                                   dragSource.startDrag(event, DragSource.DefaultLinkDrop,

                                                 (Transferable) src, new MyDragSourceListener());

                                   setDragLine(src, new DefaultLinkable(pt));

                                   repaint();

                                   return;

                            }

                     }

              }

       }

      

       class MyDropTargetListener implements DropTargetListener {

              public void dragEnter(DropTargetDragEvent event) {

              }

              public void dragExit(DropTargetEvent event) {

                     bDragLine = false;

                     repaint();

              }

              public void dragOver(DropTargetDragEvent event) {

                     if (!event

                                   .isDataFlavorSupported(MapperTreeNode.mapperTreeNodeFlavor)

                                   && !event

                                                 .isDataFlavorSupported(DefaultLinkable.linkableFlavor)

                                   && !event

                                                 .isDataFlavorSupported(DefaultLinkable.localLinkableFlavor)) {

                            return;

                     }

                     Point pt = event.getLocation();

                     Transferable t = event.getTransferable(); // JDK 1.5

                     ILinkable src = DefaultLinkable.getLinkable(t);

                     ILinkable dst = new DefaultLinkable(pt);

                     IMapObject obj = ObjectPanel.this.getMap().getChildAt(pt);

                     if (obj != null && (obj instanceof ILinkable))

                            dst = (ILinkable) obj;

                     if (dst.willAccept(src)) {

                            dragLine = new LinkLine(src, dst);

                            bDragLine = true;

                            ObjectPanel.this.repaint();

                     }

              }

              public void drop(DropTargetDropEvent event) {

                     Transferable t = event.getTransferable();

                     ILinkable src = DefaultLinkable.getLinkable(t);

                     Point pt = event.getLocation();

                     IMapObject dst = ObjectPanel.this.getMap().getChildAt(pt);

                     if (dst != null && (dst instanceof ILinkable))

                            if (((ILinkable) dst).willAccept(src))

                                   addLink(src, (ILinkable) dst);

                     map.repaint();

              }

              public void dropActionChanged(DropTargetDragEvent event) {

              }

       }

      

       class MyMouseListener implements MouseListener {

              public void mouseClicked(MouseEvent e) {

              }

              public void mouseEntered(MouseEvent e) {

              }

              public void mouseExited(MouseEvent e) {

              }

              public void mousePressed(MouseEvent e) {

                     IMapObject obj = ObjectPanel.this.getMap().getChildAt(e.getPoint());

                     if (null != obj)

                            objectSelected(obj);

                     else

                            objectSelected(map);

              }

              public void mouseReleased(MouseEvent e) {

                     if (e.isPopupTrigger()) {

                            ptPopup = e.getPoint();

                            IMapObject obj = ObjectPanel.this.getMap().getChildAt(ptPopup);

                            JPopupMenu popup = new MyPopupMenu(obj);

                            popup.show(e.getComponent(), e.getX(), e.getY());

                            ObjectPanel.this.repaint();

                     }

              }

       }

鼠标事件用于设置连线的属性,可在连线上创建函数,用于数据处理。

    1. 连线定义

绘制连线的时候需要进行连线的属性定义。

import java.util.ArrayList;

import java.util.List;

/**

 * 连线属性

 * @author song0

 *

 */

public class lineMapping {

      

       private String id;//连线ID

      

       private String parentId;//父级连线ID

      

       private List<String> childNodeId;//子连线ID集合

      

       private String sourceNode;//源xpath或jpath 含有@代表属性 没有@代表节点

      

       private String targetNode;//目标xpath或jpath 含有@代表属性 没有@代表节点

      

       private String lineType;//点对点one,循环for

      

       private String sourceType;//xml,json

      

       private String targetType;//xml,json

      

       private List<String> function;//函数列表

      

       public lineMapping() {

              childNodeId=new ArrayList<String>();

              function=new ArrayList<String>();

       }

       public String getSourceNode() {

              return sourceNode;

       }

       public void setSourceNode(String sourceNode) {

              this.sourceNode = sourceNode;

       }

       public String getTargetNode() {

              return targetNode;

       }

       public void setTargetNode(String targetNode) {

              this.targetNode = targetNode;

       }

       public String getLineType() {

              return lineType;

       }

       public void setLineType(String lineType) {

              this.lineType = lineType;

       }

       public String getSourceType() {

              return sourceType;

       }

       public void setSourceType(String sourceType) {

              this.sourceType = sourceType;

       }

       public String getTargetType() {

              return targetType;

       }

       public void setTargetType(String targetType) {

              this.targetType = targetType;

       }

       public List<String> getFunction() {

              return function;

       }

       public void setFunction(List<String> function) {

              this.function = function;

       }

      

       public void addFunction(String function) {

              this.function.add(function);

       }

      

       public String getFunction(int index) {

              return this.function.get(index);

       }

       public String getId() {

              return id;

       }

       public void setId(String id) {

              this.id = id;

       }

       public String getParentId() {

              return parentId;

       }

       public void setParentId(String parentId) {

              this.parentId = parentId;

       }

       public List<String> getChildNodeId() {

              return childNodeId;

       }

       public void setChildNodeId(List<String> childNodeId) {

              this.childNodeId = childNodeId;

       }

      

       public void addChildNodeId(String childNodeId) {

              this.childNodeId.add(childNodeId);

       }

      

       public String getChildNodeId(int index) {

              return this.childNodeId.get(index);

       }

}

    1. 映射连线数据处理

另外需要写一个类根据映射连线来将左侧的源格式转换成右侧的目标格式。

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.nio.file.Files;

import java.nio.file.Paths;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.List;

import java.util.Map;

import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.serializer.SerializerFeature;

import com.google.gson.JsonArray;

import com.google.gson.JsonObject;

public class lineMap {

      

       public void xmltojson(String uri,String sourcepath,String targetpath) {

              xmltojson(uri,sourcepath,targetpath,null);

       }

      

       public void xmltojson(String uri,String sourcepath,String targetpath,LinkedHashMap<String,List<Function>> functionMap) {

              FileInputStream file;

              try {

                     file = new FileInputStream(uri);

                     String js=getStringByInputStream(file);

                     JSONObject jsonObject=JSON.parseObject(js);

                     LinkedHashMap<String,lineMapping> line=new LinkedHashMap<String, lineMapping>();

                     List<lineMapping> mappingList=new ArrayList<lineMapping>();

                     Iterator<String> keyIter=jsonObject.keySet().iterator();

                     while(keyIter.hasNext()) {

                            String key=keyIter.next();

                            lineMapping lineMap=jsonObject.getObject(key, lineMapping.class);

                            line.put(key, lineMap);

                            if(lineMap.getParentId()==null) {

                                   mappingList.add(lineMap);

                            }

                     }

                     // 解析 JSON 文件并构建树形结构

                                          JSONObject targetJsonNode = null;

                            

                             try {

                                     // 读取 JSON 文件

                                 String jsonString = new String(Files.readAllBytes(Paths.get(targetpath)));

                                 // 将 JSON 字符串解析为 JSONObject 对象

                                 targetJsonNode = JSON.parseObject(jsonString);

                                   } catch (IOException e) {

                                          e.printStackTrace();

                                   }

                            

                             //解析XML

                             SAXReader reader = new SAXReader();

                             Document doc;

                                   try {

                                          doc = reader.read(new File(sourcepath));

                                          Element rootElement=doc.getRootElement();

                                          LinkedHashMap<String, ValueFunction> valuesNodeMap=new LinkedHashMap<String, ValueFunction>();

                                          for(lineMapping lineMapping:mappingList) {

                                          executForxmltojson(rootElement,targetJsonNode,lineMapping,line,null,null,null,null,null,-1,valuesNodeMap,functionMap);

                                          }

                                   

                                 // 输出格式化后的字符串

                                    Iterator<String> keyIters=valuesNodeMap.keySet().iterator();

                                    while(keyIters.hasNext()) {

                                           String key=keyIters.next();

                                           executeJsonFunction(targetJsonNode, valuesNodeMap.get(key), key);

                                    }

                                         

                                    String pretty = JSON.toJSONString(targetJsonNode, SerializerFeature.PrettyFormat,

                                           SerializerFeature.WriteDateUseDateFormat,SerializerFeature.WriteMapNullValue,

                                           SerializerFeature.WriteNullListAsEmpty);

                                    System.out.println(pretty );

                                   } catch (DocumentException e) {

                                          e.printStackTrace();

                                   }

              } catch (FileNotFoundException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

             

       }

      

       public static String getStringByInputStream(InputStream inputStream){

              ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

              try {

                   byte[] b = new byte[10240];

                   int n;

                   while ((n = inputStream.read(b)) != -1) {

                       outputStream.write(b, 0, n);

                   }

               } catch (Exception e) {

                   try {

                       inputStream.close();

                       outputStream.close();

                   } catch (Exception e1) {

                   }

               }

               return outputStream.toString();

       }

      

       public void xmltojson() {

              //模拟连线

              List<lineMapping> mappingList=new ArrayList<lineMapping>();

              LinkedHashMap<String,lineMapping> line=new LinkedHashMap<String,lineMapping>();

                     lineMapping mapping=new lineMapping();

                     mapping.setId("00000-00001");

                     mapping.setLineType(NodeUtil.FOR);//当对应目标节点是数组的时候,连线类型是for

                     mapping.setSourceNode("array");

                     mapping.setSourceType(NodeUtil.XML);

                     mapping.setTargetNode("Assets");

                     mapping.setTargetType(NodeUtil.JSON);

                    

                    

                    

                     lineMapping child1=new lineMapping();

                     child1.setId("00000-00002");

                     child1.setLineType(NodeUtil.ONE);

                     child1.setSourceNode("array/map/map/string[0]");

                     child1.setSourceType(NodeUtil.XML);

                     child1.setTargetNode("Assets/Asset[0]/Open");

                     child1.setTargetType(NodeUtil.JSON);

                     child1.setParentId(mapping.getId());

                    

                    

                    

                     lineMapping child2=new lineMapping();

                     child2.setId("00000-00003");

                     child2.setLineType(NodeUtil.ONE);

                     child2.setSourceNode("array/map/map/string[1]");

                     child2.setSourceType(NodeUtil.XML);

                     child2.setTargetNode("Assets/Asset[0]/High");

                     child2.setTargetType(NodeUtil.JSON);

                     child2.setParentId(mapping.getId());

                    

                     lineMapping child3=new lineMapping();

                     child3.setId("00000-00004");

                     child3.setLineType(NodeUtil.ONE);

                     child3.setSourceNode("array/map/map/string[2]");

                     child3.setSourceType(NodeUtil.XML);

                     child3.setTargetNode("Assets/Asset[0]/Low");

                     child3.setTargetType(NodeUtil.JSON);

                     child3.setParentId(mapping.getId());

                    

                     lineMapping child4=new lineMapping();

                     child4.setId("00000-00005");

                     child4.setLineType(NodeUtil.ONE);

                     child4.setSourceNode("array/map/map/string[3]");

                     child4.setSourceType(NodeUtil.XML);

                     child4.setTargetNode("Assets/Asset[0]/Close");

                     child4.setTargetType(NodeUtil.JSON);

                     child4.setParentId(mapping.getId());

                    

                    

                     mapping.addChildNodeId(child1.getId());

                     mapping.addChildNodeId(child2.getId());

                     mapping.addChildNodeId(child3.getId());

                     mapping.addChildNodeId(child4.getId());

                    

                     line.put(mapping.getId(), mapping);

                     line.put(child1.getId(), child1);

                     line.put(child2.getId(), child2);

                     line.put(child3.getId(), child3);

                     line.put(child4.getId(), child4);

                     mappingList.add(mapping);

                    

              // 解析 JSON 文件并构建树形结构

                     JSONObject targetJsonNode = null;

       

       

        try {

                // 读取 JSON 文件

            String jsonString = new String(Files.readAllBytes(Paths.get("jsontoxml/input.json")));

            // 将 JSON 字符串解析为 JSONObject 对象

            targetJsonNode = JSON.parseObject(jsonString);

              } catch (IOException e) {

                     e.printStackTrace();

              }

       

        //解析XML

        SAXReader reader = new SAXReader();

        Document doc;

              try {

                     doc = reader.read(new File("xmltojson/input.xml"));

                     Element rootElement=doc.getRootElement();

              

                    

                     for(lineMapping lineMapping:mappingList) {

                            executForxmltojson(rootElement,targetJsonNode,lineMapping,line,null,null,null,null,null,-1,null,null);

                            }

              

            // 输出格式化后的字符串

               String pretty = JSON.toJSONString(targetJsonNode, SerializerFeature.PrettyFormat,

                      SerializerFeature.WriteDateUseDateFormat,SerializerFeature.WriteMapNullValue,

                      SerializerFeature.WriteNullListAsEmpty);

               System.out.println(pretty );

              } catch (DocumentException e) {

                     e.printStackTrace();

              }

             

       }

      

       /**

        * 递归

        * @param source 来源

        * @param target 目标

        * @param lineMapping 连线映射

        * @param line 连线映射

        * @param parentLineType 父连线类型

        * @param parentTarget    父目标

        * @param temp 父目标

        * @param tempEle 父来源

        * @param parentlineMapping 父连线映射

        * @param index  for循环索引

        * @param targetNodeMap 目标函数与值的映射

        * @param functionMap 函数映射map

        */

       public void executForxmltojson(Element source,Object  target,lineMapping lineMapping,LinkedHashMap<String,lineMapping> line,String parentLineType,Object  parentTarget,Object temp,Element tempEle,lineMapping parentlineMapping,int index,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              String parentSourcePath=null;

              String parentTargetPath=null;

              if(parentlineMapping!=null) {

                     parentSourcePath=parentlineMapping.getSourceNode();

                     parentTargetPath=parentlineMapping.getTargetNode();

              }

              if(lineMapping.getLineType().equals(NodeUtil.FOR)) {

                     Element sourcetemp=source;

                     Object targettemp=target;

                     Element parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

                     Attribute attribute=null;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                    

               Map<String,Object> sourcemap=getSourceXmlPathNode(parentSourcePath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

               sourcetemp=(Element) sourcemap.get("sourcetemp");

               sourcePathNode=(PathNode) sourcemap.get("sourcePathNode");

               parentsourcetemp=(Element) sourcemap.get("parentsourcetemp");

               attribute=(Attribute) sourcemap.get("attribute");

              

               Map<String,Object> map=getTargetJsonPathNode(parentTargetPath, lineMappingtemp, targettemp, temp, targetPathNode, parentTargettemp);

               targettemp=map.get("targettemp");

               targetPathNode=(PathNode) map.get("targetPathNode");

               parentTargettemp=map.get("parentTargettemp");

              

              

               //当连线类型是for时

               forxmltojson(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, targetPathNode, line,targettemp,targetNodeMap,functionMap);

              

              

                     

              }else {

                     Element sourcetemp=source;

                     Object targettemp=target;

                     Element parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

                    

                     Attribute attribute=null;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                     Map<String,Object> sourcemap=getSourceXmlPathNode(parentSourcePath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

               sourcetemp=(Element) sourcemap.get("sourcetemp");

               sourcePathNode=(PathNode) sourcemap.get("sourcePathNode");

               parentsourcetemp=(Element) sourcemap.get("parentsourcetemp");

               attribute=(Attribute) sourcemap.get("attribute");

              

               Map<String,Object> map=getTargetJsonPathNode(parentTargetPath, lineMappingtemp, targettemp, temp, targetPathNode, parentTargettemp);

               targettemp=map.get("targettemp");

               targetPathNode=(PathNode) map.get("targetPathNode");

               parentTargettemp=map.get("parentTargettemp");

               if(parentLineType!=null&&!parentLineType.equals(NodeUtil.FOR)) {

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltojson(parentTargettemp, sourcePathNode, targetPathNode);

                      }

               }else {

                      if(parentTargettemp!=null&&parentTargetPath!=null) {

                             setValueFunction(parentTargetPath, sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                             targettemp=parentTargettemp;

                      }else {

                             setValueFunction(lineMapping.getTargetNode(), sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                      }

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltojson(parentTargettemp, sourcePathNode, targetPathNode);

                      }

               }

              

               

              }

             

       }

      

       /**

        * 处理目标函数于值的对应关系

        * @param parentTargetPath

        * @param sourcePathNode

        * @param targetPathNode

        * @param lineMapping

        * @param index

        * @param targetNodeMap

        * @param functionMap

        */

       public void setValueFunction(String parentTargetPath,PathNode sourcePathNode,PathNode targetPathNode,lineMapping lineMapping,int index,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              if(functionMap!=null&&functionMap.containsKey(lineMapping.getTargetNode())) {

                     String targetPath=null;

                     String targetNodePath=null;

                     if(index!=-1) {

                         targetPath=lineMapping.getTargetNode().substring(parentTargetPath.length(), lineMapping.getTargetNode().length());

                         targetNodePath=removeArr(parentTargetPath,index)+targetPath;

                     }else {

                            targetNodePath=lineMapping.getTargetNode();

                     }

                  if(targetNodeMap.containsKey(targetNodePath)) {

                         ValueFunction function=targetNodeMap.get(targetNodePath);

                         function.getValue().add(sourcePathNode.getValue());

                         function.setFunctionList(functionMap.get(lineMapping.getTargetNode()));

                  }else {

                         ValueFunction valueFunction=new ValueFunction();

                         valueFunction.getValue().add(sourcePathNode.getValue());

                         valueFunction.setFunctionList(functionMap.get(lineMapping.getTargetNode()));

                         targetNodeMap.put(targetNodePath, valueFunction);

                  }

              }

       }

      

       /**

        * 将所有的函数循环处理里面的值

        * @param json

        * @param valuefunction

        * @param path

        */

       public void executeXmlFunction(Element json,ValueFunction valuefunction,String path) {

              List<Function> functionList=valuefunction.getFunctionList();

                     for(int i=0;i<functionList.size();i++) {

                            Function function=functionList.get(i);

                            switch (function.getTargetType()) {

                            case "addvalue":

                                   addXmlvalueFunction(valuefunction.getValue(), function, json, path);

                                   break;

      

                            default:

                                   break;

                            }

                     }

       }

      

       public void addXmlvalueFunction(List<Object> list,Function function,Element json,String path) {

              for(int i=0;i<list.size();i++) {

                     Object obj=list.get(i);

                     obj=obj.toString()+function.getBody().toString();

                     //获取xml路径

                     String[] paths=path.split("/");

                    

                     Attribute attribute=null;

                     PathNode targetPathNode = null;

                     Element targettemp=json;

              

               //找到目标节点

               for(int j=0;j<paths.length;j++) {

                      if(j==1) {

                             continue;

                      }

                      if(j==0) {

                             continue;

                      }

                      targetPathNode=getNodeName(paths[j]);

                      if(targetPathNode.getName().equals("")) {

                             continue;

                      }

                      if(targetPathNode.getType().equals(NodeUtil.TEXT)) {

                             targettemp=targettemp.element(targetPathNode.getName());

                             targetPathNode.setValue(targettemp.getText());

                      }else if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                             attribute=targettemp.attribute(targetPathNode.getName());

                             targetPathNode.setValue(attribute.getValue());

                      }else if(targetPathNode.getType().equals(NodeUtil.ARRAY)) {

                             targettemp=targettemp.elements().get(targetPathNode.getIndex());

                                    targetPathNode.setValue(targettemp.getText());

                      }

               }

                     if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                         attribute.setValue(obj.toString());

                  }else {

                         targettemp.setText(obj.toString());

                  }

                    

              }

       }

      

       /**

        * 将所有的函数循环处理里面的值

        * @param json

        * @param valuefunction

        * @param path

        */

       public void executeJsonFunction(Object json,ValueFunction valuefunction,String path) {

              List<Function> functionList=valuefunction.getFunctionList();

                     for(int i=0;i<functionList.size();i++) {

                            Function function=functionList.get(i);

                            switch (function.getTargetType()) {

                            case "addvalue":

                                   addJsonvalueFunction(valuefunction.getValue(), function, json, path);

                                   break;

      

                            default:

                                   break;

                            }

                     }

       }

      

       /**

        * 执行添加固定值函数

        * @param list

        * @param function

        * @param json

        * @param path

        */

       public void addJsonvalueFunction(List<Object> list,Function function,Object json,String path) {

                     for(int i=0;i<list.size();i++) {

                            Object obj=list.get(i);

                            obj=obj.toString()+function.getBody().toString();

                            String[] jsonPaths=null;

                            jsonPaths=path.split("/");

                            Object targettemp=json;

                            Object parenttemp=null;

                            PathNode targetPathNode = null;

                            for(int j=0;j<jsonPaths.length;j++) {

                             targetPathNode=getNodeName(jsonPaths[j]);

                             if(targetPathNode.getName()!=null&&targetPathNode.getName().equals("")) {

                                    continue;

                             }

                             if(targettemp!=null) {

                                    parenttemp=targettemp;

                             }

                             if(targetPathNode.getType().equals(NodeUtil.TEXT)) {

                                    targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

                             }else if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                                    targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

                                   

                             }else if(targetPathNode.getType().equals(NodeUtil.ARRAY)) {

                                    targettemp=((JSONArray)targettemp).get(targetPathNode.getIndex());

                             }

                      }

                            if (targettemp instanceof JSONArray) {

                          //System.out.println("target 是一个 JSON 数组");

                                   JSONArray jsonarray=((JSONArray) targettemp);

                                   Object objjson=jsonarray.get(targetPathNode.getIndex());

                                   if(objjson instanceof JSONArray) {

                                         

                                   }else {

                                          ((JSONObject)objjson).put(targetPathNode.getName(), obj);

                                   }

                      } else {

                             ((JSONObject)parenttemp).put(targetPathNode.getName(), obj);

                      }

                     }

       }

      

       /**

        * 将索引值去除换成新值

        * @param path

        * @return

        */

       public String removeArr(String path,int index) {

              if(path.lastIndexOf("[")!=-1) {

                     path=path.substring(0,path.lastIndexOf("["))+"["+index+"]";

              }

              return path;

       }

      

       /**

        * 克隆json对象

        * @param obj

        * @return

        */

       public Object jsonClone(Object obj) {

              Object clone=null;

              if(obj instanceof JSONArray) {

                     clone=JSON.parseArray(((JSONArray)obj).toJSONString());

              }else {

                     clone=JSON.parseObject(((JSONObject)obj).toJSONString());

              }

              return clone;

       }

      

       /**

        * 解析连线节点对象

        * @param pathName

        * @return

        */

       public PathNode getNodeName(String pathName) {

              PathNode node=new PathNode();

             

              if(pathName.startsWith("@")) {

                     node.setType(NodeUtil.ATTR);

                     node.setName(pathName.substring(1, pathName.length()));

                     return node;

              }

             

              if(pathName.indexOf("[")>0&&pathName.endsWith("]")) {

                     node.setType(NodeUtil.ARRAY);

                     int flag=pathName.indexOf("[");

                     String name=pathName.substring(0, flag);

                     String num=pathName.substring(flag+1,pathName.lastIndexOf("]"));

                     node.setName(name);

                     if(num.equals("")) {

                            node.setIndex(0);

                     }else {

                            node.setIndex(Integer.parseInt(num));

                     }

                     return node;

              }

             

              if(pathName.startsWith("[")&&pathName.endsWith("]")) {

                     node.setType(NodeUtil.ARRAY);

                     String num=pathName.substring(1,pathName.lastIndexOf("]"));

                     if(num.equals("")) {

                            node.setIndex(0);

                     }else {

                            node.setIndex(Integer.parseInt(num));

                     }

                     return node;

              }

             

              node.setName(pathName);

              node.setType(NodeUtil.TEXT);

              return node;

       }

      

       public void jsontoxml(String uri,String sourcepath,String targetpath) {

              jsontoxml(uri,sourcepath,targetpath,null);

       }

      

       /**

        * 处理json转xml

        * @param uri

        */

       public void jsontoxml(String uri,String sourcepath,String targetpath,LinkedHashMap<String,List<Function>> functionMap) {

              FileInputStream file;

              try {

                     file = new FileInputStream(uri);

                     String js=getStringByInputStream(file);

                     JSONObject jsonObject=JSON.parseObject(js);

                     LinkedHashMap<String,lineMapping> line=new LinkedHashMap<String, lineMapping>();

                     List<lineMapping> mappingList=new ArrayList<lineMapping>();

                     Iterator<String> keyIter=jsonObject.keySet().iterator();

                     while(keyIter.hasNext()) {

                            String key=keyIter.next();

                            lineMapping lineMap=jsonObject.getObject(key, lineMapping.class);

                            line.put(key, lineMap);

                            if(lineMap.getParentId()==null) {

                                   mappingList.add(lineMap);

                            }

                     }

                     // 解析 JSON 文件并构建树形结构

                                          JSONObject targetJsonNode = null;

                            

                            

                             try {

                                     // 读取 JSON 文件

                                 String jsonString = new String(Files.readAllBytes(Paths.get(sourcepath)));

                                 // 将 JSON 字符串解析为 JSONObject 对象

                                 targetJsonNode = JSON.parseObject(jsonString);

                                   } catch (IOException e) {

                                          e.printStackTrace();

                                   }

                            

                             //解析XML

                             SAXReader reader = new SAXReader();

                             Document doc;

                                   try {

                                          doc = reader.read(new File(targetpath));

                                          Element rootElement=doc.getRootElement();

                                          //当连线类型是for时进行递归

                                    LinkedHashMap<String, ValueFunction> valuesNodeMap=new LinkedHashMap<String, ValueFunction>();

                                          for(lineMapping lineMapping:mappingList) {

                                                 executForjsontoxml(rootElement,targetJsonNode,lineMapping,line,null,null,null,null,null,-1,valuesNodeMap,functionMap);

                                          }

                                   

                                 // 输出格式化后的字符串

                                   

                                    Iterator<String> keyIters=valuesNodeMap.keySet().iterator();

                                    while(keyIters.hasNext()) {

                                           String key=keyIters.next();

                                           executeXmlFunction(rootElement, valuesNodeMap.get(key),key);

                                    }

                                    System.out.println(doc.asXML() );

                                   } catch (DocumentException e) {

                                          e.printStackTrace();

                                   }

              } catch (FileNotFoundException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

       }

      

       /**

        * 处理目标json

        * @param parentTargetPath

        * @param lineMappingtemp

        * @param targettemp

        * @param temp

        * @param targetPathNode

        * @param parentTargettemp

        */

       public Map<String,Object> getTargetJsonPathNode(String parentTargetPath,lineMapping lineMappingtemp,Object targettemp,Object temp,PathNode targetPathNode,Object parentTargettemp) {

              String[] jsonPaths=null;

        if(parentTargetPath!=null) {

               jsonPaths=lineMappingtemp.getTargetNode().substring(parentTargetPath.length(), lineMappingtemp.getTargetNode().length()).split("/");

               targettemp=temp;

              }else {

                     jsonPaths=lineMappingtemp.getTargetNode().split("/");

              }

       

        for(int i=0;i<jsonPaths.length;i++) {

               if(i<jsonPaths.length) {

                      parentTargettemp=targettemp;

               }

               targetPathNode=getNodeName(jsonPaths[i]);

               if(targetPathNode.getName()!=null&&targetPathNode.getName().equals("")) {

                      continue;

               }

               if(targetPathNode.getType().equals(NodeUtil.TEXT)) {

                      targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

               }else if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                      targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

                     

               }else if(targetPathNode.getType().equals(NodeUtil.ARRAY)) {

                      targettemp=((JSONArray)targettemp).get(targetPathNode.getIndex());

                     

               }

        }

       

        Map<String,Object> map=new HashMap<String, Object>();

        map.put("targettemp", targettemp);

        map.put("targetPathNode", targetPathNode);

        map.put("parentTargettemp", parentTargettemp);

        return map;

       }

      

       /**

        * 处理来源json

        * @param parentSourcePath

        * @param lineMappingtemp

        * @param targettemp

        * @param temp

        * @param targetPathNode

        * @param parentTargettemp

        */

       public Map<String,Object> getSourceJsonPathNode(String parentSourcePath,lineMapping lineMappingtemp,Object targettemp,Object temp,PathNode targetPathNode,Object parentTargettemp) {

              //处理来源json

              //获取json路径

              String[] jsonPaths=null;

        if(parentSourcePath!=null) {//判断是否有父路径

               //使用父路径进行对当前路径进行截取

               jsonPaths=lineMappingtemp.getSourceNode().substring(parentSourcePath.length(), lineMappingtemp.getSourceNode().length()).split("/");

               targettemp=temp;

              }else {

                     jsonPaths=lineMappingtemp.getSourceNode().split("/");

              }

       

        //找到数据来源节点

        for(int i=0;i<jsonPaths.length;i++) {

               if(i<jsonPaths.length) {

                      parentTargettemp=targettemp;

               }

               targetPathNode=getNodeName(jsonPaths[i]);

               if(targetPathNode.getName()!=null&&targetPathNode.getName().equals("")) {

                      continue;

               }

               if(targetPathNode.getType().equals(NodeUtil.TEXT)) {

                      targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

                      if(targettemp!=null) {

                             targetPathNode.setValue(targettemp.toString());

                      }

               }else if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                      targettemp=((JSONObject)targettemp).get(targetPathNode.getName());

                     

               }else if(targetPathNode.getType().equals(NodeUtil.ARRAY)) {

                      targettemp=((JSONArray)targettemp).get(targetPathNode.getIndex());

                     

                      if(targettemp!=null) {

                             targetPathNode.setValue(targettemp.toString());

                      }

               }

        }

        Map<String,Object> map=new HashMap<String, Object>();

        map.put("sourcetemp", targettemp);

        map.put("sourcePathNode", targetPathNode);

        map.put("parentsourcetemp", parentTargettemp);

        return map;

       }

      

       /**

        * 处理源xml

        * @param parentSourcePath

        * @param lineMappingtemp

        * @param sourcetemp

        * @param tempEle

        * @param sourcePathNode

        * @param parentsourcetemp

        * @param attribute

        */

       public Map<String,Object> getSourceXmlPathNode(String parentSourcePath,lineMapping lineMappingtemp,Element sourcetemp,Element tempEle,PathNode sourcePathNode,Element parentsourcetemp,Attribute attribute) {

              String[] paths=null;

              if(parentSourcePath!=null) {

                     paths=lineMappingtemp.getSourceNode().substring(parentSourcePath.length(), lineMappingtemp.getSourceNode().length()).split("/");

                     sourcetemp=tempEle;

              }else {

                     paths=lineMappingtemp.getSourceNode().split("/");

              }

       

       

        for(int i=0;i<paths.length;i++) {

               if(parentSourcePath==null&&i==1) {

                      continue;

               }

               if(i==0) {

                      continue;

               }else if(i<paths.length) {

                      parentsourcetemp=sourcetemp;

               }

               sourcePathNode=getNodeName(paths[i]);

               if(sourcePathNode.getName().equals("")) {

                      continue;

               }

               if(sourcePathNode.getType().equals(NodeUtil.TEXT)) {

                      sourcetemp=sourcetemp.element(sourcePathNode.getName());

                      sourcePathNode.setValue(sourcetemp.getText());

               }else if(sourcePathNode.getType().equals(NodeUtil.ATTR)) {

                      attribute=sourcetemp.attribute(sourcePathNode.getName());

                      sourcePathNode.setValue(attribute.getValue());

               }else if(sourcePathNode.getType().equals(NodeUtil.ARRAY)) {

                             sourcetemp=sourcetemp.elements().get(sourcePathNode.getIndex());

                             sourcePathNode.setValue(sourcetemp.getText());

               }

        }

        Map<String,Object> map=new HashMap<String, Object>();

        map.put("sourcetemp", sourcetemp);

        map.put("sourcePathNode", sourcePathNode);

        map.put("parentsourcetemp", parentsourcetemp);

        map.put("attribute", attribute);

        return map;

       }

      

       /**

        * 处理目标xml

        * @param parentTargetPath

        * @param lineMappingtemp

        * @param sourcetemp

        * @param tempEle

        * @param sourcePathNode

        * @param parentsourcetemp

        * @param attribute

        */

       public Map<String,Object> getTargetXmlPathNode(String parentTargetPath,lineMapping lineMappingtemp,Element sourcetemp,Element tempEle,PathNode sourcePathNode,Element parentsourcetemp,Attribute attribute) {

              //获取xml路径

              String[] paths=null;

              if(parentTargetPath!=null) {//判断是否有父路径

                     //使用父路径进行对当前路径进行截取

                     paths=lineMappingtemp.getTargetNode().substring(parentTargetPath.length(), lineMappingtemp.getTargetNode().length()).split("/");

                     sourcetemp=tempEle;

              }else {

                     paths=lineMappingtemp.getTargetNode().split("/");

              }

       

        //找到目标节点

        for(int i=0;i<paths.length;i++) {

               if(parentTargetPath==null&&i==1) {

                      continue;

               }

               if(i==0) {

                      continue;

               }else if(i<paths.length) {

                      parentsourcetemp=sourcetemp;

               }

               sourcePathNode=getNodeName(paths[i]);

               if(sourcePathNode.getName().equals("")) {

                      continue;

               }

               if(sourcePathNode.getType().equals(NodeUtil.TEXT)) {

                      sourcetemp=sourcetemp.element(sourcePathNode.getName());

                      sourcePathNode.setValue(sourcetemp.getText());

               }else if(sourcePathNode.getType().equals(NodeUtil.ATTR)) {

                      attribute=sourcetemp.attribute(sourcePathNode.getName());

                      sourcePathNode.setValue(attribute.getValue());

               }else if(sourcePathNode.getType().equals(NodeUtil.ARRAY)) {

                             sourcetemp=sourcetemp.elements().get(sourcePathNode.getIndex());

                             sourcePathNode.setValue(sourcetemp.getText());

               }

        }

       

        Map<String,Object> map=new HashMap<String, Object>();

        map.put("targettemp", sourcetemp);

        map.put("targetPathNode", sourcePathNode);

        map.put("parentTargettemp", parentsourcetemp);

        map.put("targetAttribute", attribute);

        return map;

       }

      

       /**

        * 递归处理xml到json的转换

        * @param parentTargettemp

        * @param parentsourcetemp

        * @param sourcePathNode

        * @param targetPathNode

        * @param lineMapping

        * @param source

        * @param target

        * @param line

        * @param targettemp

        * @param valuesNodeMap

        * @param functionMap

        */

       public void forxmltojson(Object parentTargettemp,Element parentsourcetemp,PathNode sourcePathNode,PathNode targetPathNode,lineMapping lineMapping,Element source,Object  target,LinkedHashMap<String,lineMapping> line,Object  targettemp,LinkedHashMap<String, ValueFunction> valuesNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              int num=0;

           List<Element> elements=parentsourcetemp.elements(sourcePathNode.getName());

              for(int i=0;i<elements.size();i++) {

                     Object ttemp=jsonClone(targettemp);

               for(String key:lineMapping.getChildNodeId()) {

                     

                             executForxmltojson(source,target,line.get(key),line,NodeUtil.FOR,parentTargettemp,ttemp,elements.get(i),lineMapping,i,valuesNodeMap,functionMap);

                            

                        

                           

                  }

               if(parentTargettemp!=null) {

                      if (parentTargettemp instanceof JSONArray) {

                             if(num==0) {

                                    ((JSONArray)parentTargettemp).clear();

                             }

                             ((JSONArray)parentTargettemp).add((ttemp));

                      }else {

                            

                      }

               }

                     num++;

                    

              }

       }

      

       /**

        * 递归处理json到xml的转换

        * @param parentTargettemp

        * @param parentsourcetemp

        * @param sourcePathNode

        * @param targetPathNode

        * @param lineMapping

        * @param source

        * @param target

        * @param line

        */

       public void forjsontoxml(Object parentTargettemp,Element parentsourcetemp,PathNode sourcePathNode,PathNode targetPathNode,lineMapping lineMapping,Element source,Object  target,LinkedHashMap<String,lineMapping> line,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              int num=0;

           //当连线是for是parentTargettemp类型应该是JSONArray

           if (parentTargettemp instanceof JSONArray) {

                  JSONArray array=(JSONArray) parentTargettemp;

                  Element element=null;

                  //循环处理parentTargettemp数组中的所有数据

                  for(int i=0;i<array.size();i++) {

                         Object jsonobj=array.get(i);

                         if(!(jsonobj instanceof JSONArray)&&!(jsonobj instanceof JSONObject)) {

                                //目标节点复制对象,避免后期修改出现数据替换

                                if(element==null) {

                                       element=parentsourcetemp.createCopy();

                                }else {

                                       element=element.createCopy();

                                }

                               

                                Element elementarr=element.element(sourcePathNode.getName()).createCopy();

                                element.clearContent();//清空对象内容

                                elementarr.setText(jsonobj.toString());

                               

                                element.add(elementarr);//添加对象

                                if(parentsourcetemp!=null) {

                                       if(num==0) {//第一次时需要将目标模版中的对象清空

                                              parentsourcetemp.clearContent();;

                                    }

                                       parentsourcetemp.add(elementarr.createCopy());

                                }

                                num++;

                         }else {

                               

                                //目标节点复制对象,避免后期修改出现数据替换

                                if(element==null) {

                                       element=parentsourcetemp.createCopy();

                                }else {

                                       element=element.createCopy();

                                }

                               

                                Element elementarr=element.element(sourcePathNode.getName()).createCopy();

                                element.clearContent();//清空对象内容

                               

                               

                                for(String key:lineMapping.getChildNodeId()) {

                                      

                                       executForjsontoxml(source,target,line.get(key),line,NodeUtil.FOR,parentTargettemp,jsonobj,elementarr,lineMapping,i,targetNodeMap,functionMap);

                                }

                                element.add(elementarr);//添加对象

                                if(parentsourcetemp!=null) {

                                       if(num==0) {//第一次时需要将目标模版中的对象清空

                                              parentsourcetemp.clearContent();;

                                    }

                                       parentsourcetemp.add(elementarr.createCopy());

                                }

                                num++;

                               

                               

                         }

                  }

           }

       }

      

       /**

        * 处理叶子节点xml到json数据

        * @param targettemp

        * @param sourcePathNode

        * @param targetPathNode

        */

       public void onexmltojson(Object targettemp,PathNode sourcePathNode,PathNode targetPathNode) {

              if (targettemp instanceof JSONArray) {

            //System.out.println("target 是一个 JSON 数组");

                     JSONArray jsonarray=((JSONArray) targettemp);

                     Object obj=jsonarray.get(targetPathNode.getIndex());

                     if(obj instanceof JSONArray) {

                           

                     }else {

                            ((JSONObject)obj).put(targetPathNode.getName(), sourcePathNode.getValue());

                     }

        } else {

               ((JSONObject)targettemp).put(targetPathNode.getName(), sourcePathNode.getValue());

        }

       }

      

       /**

        * 处理叶子节点json到xml数据

        * @param sourcePathNode

        * @param targetPathNode

        * @param attribute

        * @param sourcetemp

        */

       public void onejsontoxml(PathNode sourcePathNode,PathNode targetPathNode,Attribute attribute,Element sourcetemp) {

              if(sourcePathNode.getType().equals(NodeUtil.ATTR)) {

                  attribute.setValue(targetPathNode.getValue());

           }else {

                  sourcetemp.setText(targetPathNode.getValue());

           }

       }

      

       /**

        * 递归执行json到xml转换

        * @param source

        * @param target

        * @param lineMapping

        * @param line

        * @param parentLineType

        * @param parentTarget

        * @param temp

        * @param tempEle

        * @param parentlineMapping

        */

       public void executForjsontoxml(Element source,Object  target,lineMapping lineMapping,LinkedHashMap<String,lineMapping> line,String parentLineType,Object  parentTarget,Object temp,Element tempEle,lineMapping parentlineMapping,int index,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              String parentSourcePath=null;

              String parentTargetPath=null;

              //判断是否有父路径

              if(parentlineMapping!=null) {

                     parentSourcePath=parentlineMapping.getSourceNode();

                     parentTargetPath=parentlineMapping.getTargetNode();

              }

             

              //判断是否包含循环

              if(lineMapping.getLineType().equals(NodeUtil.FOR)) {

                     Element sourcetemp=source;

                     Object targettemp=target;

                     Element parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     Attribute attribute=null;

               PathNode sourcePathNode = null;//目标路径节点

                     PathNode targetPathNode = null;//来源路径节点

                    

                     lineMapping lineMappingtemp=lineMapping;

                    

                     Map<String,Object> mapsource=getSourceJsonPathNode(parentSourcePath, lineMappingtemp, targettemp, temp, sourcePathNode, parentsourcetemp);

                     targettemp=mapsource.get("sourcetemp");

                      targetPathNode=(PathNode) mapsource.get("sourcePathNode");

                      parentTargettemp=mapsource.get("parentsourcetemp");

                    

                     Map<String,Object> targetmap=getTargetXmlPathNode(parentTargetPath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

                     sourcetemp=(Element) targetmap.get("targettemp");

                     sourcePathNode=(PathNode) targetmap.get("targetPathNode");

                     parentsourcetemp=(Element) targetmap.get("parentTargettemp");

               attribute=(Attribute) targetmap.get("targetAttribute");

              

              

               forjsontoxml(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, targetPathNode, line,targetNodeMap,functionMap);

                     

              

                           

              }else {

                     Element sourcetemp=source;

                     Object targettemp=target;

                     Element parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

                    

                     Attribute attribute=null;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                     Map<String,Object> mapsource=getSourceJsonPathNode(parentSourcePath, lineMappingtemp, targettemp, temp, sourcePathNode, parentsourcetemp);

                     targettemp=mapsource.get("sourcetemp");

                      targetPathNode=(PathNode) mapsource.get("sourcePathNode");

                      parentTargettemp=mapsource.get("parentsourcetemp");

                    

                     Map<String,Object> targetmap=getTargetXmlPathNode(parentTargetPath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

                     sourcetemp=(Element) targetmap.get("targettemp");

                     sourcePathNode=(PathNode) targetmap.get("targetPathNode");

                     parentsourcetemp=(Element) targetmap.get("parentTargettemp");

               attribute=(Attribute) targetmap.get("targetAttribute");

                    

                    

              

               if(parentLineType!=null&&!parentLineType.equals(NodeUtil.FOR)) {

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onejsontoxml(sourcePathNode, targetPathNode, attribute, parentsourcetemp);

                      }else if(lineMappingtemp.getLineType().equals(NodeUtil.FOR)) {//当连线类型是for时

                             //当连线类型是for时进行递归

                             LinkedHashMap<String, ValueFunction> valuesNodeMap=new LinkedHashMap<String, ValueFunction>();

                             forjsontoxml(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, targetPathNode, line,valuesNodeMap,functionMap);

                             Iterator<String> keyIter=valuesNodeMap.keySet().iterator();

                             while(keyIter.hasNext()) {

                                    String key=keyIter.next();

                                    executeXmlFunction(source, valuesNodeMap.get(key),key);

                             }

                      }

               }else {

                      if(parentTargettemp!=null&&parentTargetPath!=null) {

                             setValueFunction(parentTargetPath, sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                             targettemp=parentTargettemp;

                      }else {

                             setValueFunction(lineMapping.getTargetNode(), sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                      }

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onejsontoxml(sourcePathNode, targetPathNode, attribute, sourcetemp);

                      }

               }

              

               

              }

       }

      

       /**

        *

        * @param uri

        */

       public void xmltoxml(String uri,String sourcepath,String targetpath) {

              xmltoxml(uri,sourcepath,targetpath,null);

       }

      

      

       /**

        * xml转xml

        * @param uri

        */

       public void xmltoxml(String uri,String sourcepath,String targetpath,LinkedHashMap<String,List<Function>> functionMap) {

              FileInputStream file;

              try {

                     file = new FileInputStream(uri);

                     String js=getStringByInputStream(file);

                     JSONObject jsonObject=JSON.parseObject(js);

                     LinkedHashMap<String,lineMapping> line=new LinkedHashMap<String, lineMapping>();

                     List<lineMapping> mappingList=new ArrayList<lineMapping>();

                     Iterator<String> keyIter=jsonObject.keySet().iterator();

                     while(keyIter.hasNext()) {

                            String key=keyIter.next();

                            lineMapping lineMap=jsonObject.getObject(key, lineMapping.class);

                            line.put(key, lineMap);

                            if(lineMap.getParentId()==null) {

                                   mappingList.add(lineMap);

                            }

                     }

                            

                             //解析XML

                             SAXReader reader = new SAXReader();

                             Document doc;

                             Document targetdoc;

                                   try {

                                          doc = reader.read(new File(sourcepath));

                                          targetdoc=reader.read(new File(targetpath));

                                          Element rootElement=doc.getRootElement();

                                          Element rootTargetElement=targetdoc.getRootElement();

                                          LinkedHashMap<String, ValueFunction> valuesNodeMap=new LinkedHashMap<String, ValueFunction>();

                                   

                                          for(lineMapping lineMapping:mappingList) {

                                                 executForxmltoxml(rootElement, rootTargetElement, lineMapping, line, null, null, null, null, null,-1,valuesNodeMap,functionMap);

                                          }

                                   

                                 // 输出格式化后的字符串

                                         

                                    Iterator<String> keyIters=valuesNodeMap.keySet().iterator();

                                    while(keyIters.hasNext()) {

                                           String key=keyIters.next();

                                           executeXmlFunction(rootTargetElement, valuesNodeMap.get(key),key);

                                    }

                                   

                                    System.out.println(targetdoc.asXML());

                                   } catch (DocumentException e) {

                                          e.printStackTrace();

                                   }

              } catch (FileNotFoundException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

       }

      

       /**

        * 递归处理xml转xml

        * @param source

        * @param target

        * @param lineMapping

        * @param line

        * @param parentLineType

        * @param parentTarget

        * @param temp

        * @param tempEle

        * @param parentlineMapping

        */

       public void executForxmltoxml(Element source,Element  target,lineMapping lineMapping,LinkedHashMap<String,lineMapping> line,String parentLineType,Element  parentTarget,Element temp,Element tempEle,lineMapping parentlineMapping,int index,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              String parentSourcePath=null;

              String parentTargetPath=null;

              if(parentlineMapping!=null) {

                     parentSourcePath=parentlineMapping.getSourceNode();

                     parentTargetPath=parentlineMapping.getTargetNode();

              }

              if(lineMapping.getLineType().equals(NodeUtil.FOR)) {

                     Element sourcetemp=source;

                     Element parentsourcetemp=null;

                     Element parentTargettemp=target;

                    

                     lineMapping lineMappingtemp=lineMapping;

                     Attribute attribute=null;

                     Attribute targetAttribute=null;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                    

               Map<String,Object> sourcemap=getSourceXmlPathNode(parentSourcePath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

               sourcetemp=(Element) sourcemap.get("sourcetemp");

               sourcePathNode=(PathNode) sourcemap.get("sourcePathNode");

               parentsourcetemp=(Element) sourcemap.get("parentsourcetemp");

               attribute=(Attribute) sourcemap.get("attribute");

              

               getTargetXmlPathNode(parentTargetPath, lineMappingtemp, parentTargettemp, tempEle, targetPathNode, parentTargettemp, targetAttribute);

              

              

               //当连线类型是for时

                      //forxmltojson(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, targetPathNode, line,targettemp);

                      forxmltoxml(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, target, line, parentTargettemp,targetNodeMap,functionMap);

                     

              }else {

                     Element sourcetemp=source;

                     Element targettemp=target;

                     Element parentsourcetemp=null;

                     Element parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

                    

                     Attribute attribute=null;

                     Attribute targetAttribute=null;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                     Map<String,Object> sourcemap=getSourceXmlPathNode(parentSourcePath, lineMappingtemp, sourcetemp, tempEle, sourcePathNode, parentsourcetemp, attribute);

               sourcetemp=(Element) sourcemap.get("sourcetemp");

               sourcePathNode=(PathNode) sourcemap.get("sourcePathNode");

               parentsourcetemp=(Element) sourcemap.get("parentsourcetemp");

               attribute=(Attribute) sourcemap.get("attribute");

              

               Map<String,Object> targetmap=getTargetXmlPathNode(parentTargetPath, lineMappingtemp, targettemp, tempEle, targetPathNode, parentTargettemp, targetAttribute);

               targettemp=(Element) targetmap.get("targettemp");

               targetPathNode=(PathNode) targetmap.get("targetPathNode");

               parentTargettemp=(Element) targetmap.get("parentTargettemp");

               targetAttribute=(Attribute) targetmap.get("targetAttribute");

              

               if(parentLineType!=null&&!parentLineType.equals(NodeUtil.FOR)) {

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltoxml(sourcePathNode, targetPathNode, targetAttribute, parentTargettemp);

                      }

               }else {

                      if(parentTargettemp!=null&&parentTargetPath!=null) {

                             setValueFunction(parentTargetPath, sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                             //targettemp=parentTargettemp;

                      }else {

                             setValueFunction(lineMapping.getTargetNode(), sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                      }

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltoxml(sourcePathNode, targetPathNode, targetAttribute, targettemp);

                      }

               }

              

               

              }

       }

      

       /**

        * 处理叶子节点xml到xml的数据

        * @param sourcePathNode

        * @param targetPathNode

        * @param attribute

        * @param sourcetemp

        */

       public void onexmltoxml(PathNode sourcePathNode,PathNode targetPathNode,Attribute attribute,Element sourcetemp) {

              if(targetPathNode.getType().equals(NodeUtil.ATTR)) {

                  attribute.setValue(sourcePathNode.getValue());

           }else {

                  sourcetemp.setText(sourcePathNode.getValue());

           }

       }

      

       /**

        * 递归处理xml转xml

        * @param parentTargettemp

        * @param parentsourcetemp

        * @param sourcePathNode

        * @param targetPathNode

        * @param lineMapping

        * @param source

        * @param target

        * @param line

        * @param targettemp

        */

       public void forxmltoxml(Element parentTargettemp,Element parentsourcetemp,PathNode sourcePathNode,PathNode targetPathNode,lineMapping lineMapping,Element source,Element  target,LinkedHashMap<String,lineMapping> line,Element  targettemp,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              int num=0;

           List<Element> elements=parentsourcetemp.elements(sourcePathNode.getName());

           Element element=null;

              for(int i=0;i<elements.size();i++) {

                     if(element==null) {

                            element=parentsourcetemp.createCopy();

                     }else {

                            element=element.createCopy();

                     }

                    

                     Element elementarr=element.element(sourcePathNode.getName()).createCopy();

                     element.clearContent();//清空对象内容

               for(String key:lineMapping.getChildNodeId()) {

                     

                      executForxmltoxml(source, target, line.get(key), line, NodeUtil.FOR, parentTargettemp, element, elementarr, lineMapping,i,targetNodeMap,functionMap);

                      //executForxmltoxml(source,target,line.get(key),line,NodeUtil.FOR,parentTargettemp,array,elements.get(i),lineMapping);

                            

                           

                  }

               element.add(elementarr);//添加对象

                     if(parentsourcetemp!=null) {

                            if(num==0) {//第一次时需要将目标模版中的对象清空

                                   parentsourcetemp.clearContent();

                      }

                            parentsourcetemp.add(element);

                     }

                     num++;

                    

              }

       }

      

       public void jsontojson(String uri,String sourcepath,String targetpath) {

              jsontojson(uri,sourcepath,targetpath,null);

       }

      

       /**

        * json转json

        * @param uri

        */

       public void jsontojson(String uri,String sourcepath,String targetpath,LinkedHashMap<String,List<Function>> functionMap) {

              FileInputStream file;

              try {

                     file = new FileInputStream(uri);

                     String js=getStringByInputStream(file);

                     JSONObject jsonObject=JSON.parseObject(js);

                     LinkedHashMap<String,lineMapping> line=new LinkedHashMap<String, lineMapping>();

                     List<lineMapping> mappingList=new ArrayList<lineMapping>();

                     Iterator<String> keyIter=jsonObject.keySet().iterator();

                     while(keyIter.hasNext()) {

                            String key=keyIter.next();

                            lineMapping lineMap=jsonObject.getObject(key, lineMapping.class);

                            line.put(key, lineMap);

                            if(lineMap.getParentId()==null) {

                                   mappingList.add(lineMap);

                            }

                     }

                     // 解析 JSON 文件并构建树形结构

                                          JSONObject targetJsonNode = null;

                                          JSONObject sourceJsonNode = null;

                            

                             try {

                                     // 读取 JSON 文件

                                 String jsonString = new String(Files.readAllBytes(Paths.get(sourcepath)));

                                 // 将 JSON 字符串解析为 JSONObject 对象

                                 sourceJsonNode = JSON.parseObject(jsonString);

                                   } catch (IOException e) {

                                          e.printStackTrace();

                                   }

                            

                            

                                   try {

                                           // 读取 JSON 文件

                                 String jsonString = new String(Files.readAllBytes(Paths.get(targetpath)));

                                 // 将 JSON 字符串解析为 JSONObject 对象

                                 targetJsonNode = JSON.parseObject(jsonString);

                                   

                                 LinkedHashMap<String, ValueFunction> valuesNodeMap=new LinkedHashMap<String, ValueFunction>();

                                

                                          for(lineMapping lineMapping:mappingList) {

                                                 executForjsontojson(sourceJsonNode,targetJsonNode,lineMapping,line,null,null,null,null,null,-1,valuesNodeMap,functionMap);

                                          }

                                   

                                 // 输出格式化后的字符串

                                         

                                          Iterator<String> keyIters=valuesNodeMap.keySet().iterator();

                                    while(keyIters.hasNext()) {

                                           String key=keyIters.next();

                                           executeJsonFunction(targetJsonNode, valuesNodeMap.get(key), key);

                                    }

                                         

                                    String pretty = JSON.toJSONString(targetJsonNode, SerializerFeature.PrettyFormat,

                                           SerializerFeature.WriteDateUseDateFormat,SerializerFeature.WriteMapNullValue,

                                           SerializerFeature.WriteNullListAsEmpty);

                                    System.out.println(pretty );

                                   } catch (IOException e) {

                                          e.printStackTrace();

                                   }

              } catch (FileNotFoundException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

       }

      

       /**

        * 递归执行json到json

        * @param source

        * @param target

        * @param lineMapping

        * @param line

        * @param parentLineType

        * @param parentTarget

        * @param temp

        * @param tempEle

        * @param parentlineMapping

        */

       public void executForjsontojson(Object source,Object  target,lineMapping lineMapping,LinkedHashMap<String,lineMapping> line,String parentLineType,Object  parentTarget,Object temp,Object tempEle,lineMapping parentlineMapping,int index,LinkedHashMap<String, ValueFunction> targetNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              String parentSourcePath=null;

              String parentTargetPath=null;

              if(parentlineMapping!=null) {

                     parentSourcePath=parentlineMapping.getSourceNode();

                     parentTargetPath=parentlineMapping.getTargetNode();

              }

              if(lineMapping.getLineType().equals(NodeUtil.FOR)) {

                     Object sourcetemp=source;

                     Object targettemp=target;

                     Object parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                    

                     Map<String,Object> mapsource=getSourceJsonPathNode(parentSourcePath, lineMappingtemp, sourcetemp, temp, sourcePathNode, parentsourcetemp);

                      sourcetemp=mapsource.get("sourcetemp");

                      sourcePathNode=(PathNode) mapsource.get("sourcePathNode");

                      parentsourcetemp=mapsource.get("parentsourcetemp");

              

               Map<String,Object> map=getTargetJsonPathNode(parentTargetPath, lineMappingtemp, targettemp, temp, targetPathNode, parentTargettemp);

               targettemp=map.get("targettemp");

               targetPathNode=(PathNode) map.get("targetPathNode");

               parentTargettemp=map.get("parentTargettemp");

              

               //当连线类型是for时

                      forjsontojson(parentTargettemp, parentsourcetemp, sourcePathNode, targetPathNode, lineMappingtemp, parentsourcetemp, targetPathNode, line,targettemp,targetNodeMap,functionMap);

                     

              }else {

                     Object sourcetemp=source;

                     Object targettemp=target;

                     Object parentsourcetemp=null;

                     Object parentTargettemp=null;

                    

                     lineMapping lineMappingtemp=lineMapping;

                    

               PathNode sourcePathNode = null;

                     PathNode targetPathNode = null;

                    

                      Map<String,Object> mapsource=getSourceJsonPathNode(parentSourcePath, lineMappingtemp, sourcetemp, sourcetemp, sourcePathNode, parentsourcetemp);

                      sourcetemp=mapsource.get("sourcetemp");

                      sourcePathNode=(PathNode) mapsource.get("sourcePathNode");

                      parentsourcetemp=mapsource.get("parentsourcetemp");

              

               Map<String,Object> map=getTargetJsonPathNode(parentTargetPath, lineMappingtemp, targettemp, temp, targetPathNode, parentTargettemp);

               targettemp=map.get("targettemp");

               targetPathNode=(PathNode) map.get("targetPathNode");

               parentTargettemp=map.get("parentTargettemp");

               if(parentLineType!=null&&!parentLineType.equals(NodeUtil.FOR)) {

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltojson(parentTargettemp, sourcePathNode, targetPathNode);

                      }

               }else {

                      if(parentTargettemp!=null&&parentTargetPath!=null) {

                             setValueFunction(parentTargetPath, sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                             targettemp=parentTargettemp;

                      }else {

                             setValueFunction(lineMapping.getTargetNode(), sourcePathNode, targetPathNode, lineMappingtemp, index, targetNodeMap, functionMap);

                      }

                      if(lineMappingtemp.getLineType().equals(NodeUtil.ONE)) {

                             onexmltojson(parentTargettemp, sourcePathNode, targetPathNode);

                      }

               }

              

               

              }

       }

      

       /**

        * 递归执行json转json

        * @param parentTargettemp

        * @param parentsourcetemp

        * @param sourcePathNode

        * @param targetPathNode

        * @param lineMapping

        * @param source

        * @param target

        * @param line

        * @param targettemp

        */

       public void forjsontojson(Object parentTargettemp,Object parentsourcetemp,PathNode sourcePathNode,PathNode targetPathNode,lineMapping lineMapping,Object source,Object  target,LinkedHashMap<String,lineMapping> line,Object  targettemp,LinkedHashMap<String, ValueFunction> valuesNodeMap,LinkedHashMap<String,List<Function>> functionMap) {

              int num=0;

              //当连线是for是parentTargettemp类型应该是JSONArray

           if (parentsourcetemp instanceof JSONArray) {

                  JSONArray array=(JSONArray) parentsourcetemp;

                  JSONArray jsonarray=null;

                  String keyparent=null;

                  //循环处理parentTargettemp数组中的所有数据

                  for(int i=0;i<array.size();i++) {

                         Object jsonobj=array.get(i);

                         if(!(jsonobj instanceof JSONArray)&&!(jsonobj instanceof JSONObject)) {

                               

                                       Object ttemp=jsonClone(targettemp);

                                       Object array2=null;

                                       if(ttemp instanceof JSONObject) {

                                              array2=((JSONObject)ttemp).get(targetPathNode.getName());

                                       }

                                    for(String key:lineMapping.getChildNodeId()) {

                                          

                                                  executForjsontojson(source,target,line.get(key),line,NodeUtil.FOR,parentTargettemp,array2,jsonobj,lineMapping,i,valuesNodeMap,functionMap);

                                                 

                                       }

                                    if(parentTargettemp!=null) {

                                           if(num==0) {

                                                  jsonarray=new JSONArray();

                                                  Iterator<String> keyIterator=((JSONObject)parentTargettemp).keySet().iterator();

                                                  while(keyIterator.hasNext()) {

                                                         keyparent=keyIterator.next();

                                                         ((JSONObject)parentTargettemp).put(keyparent, jsonarray);

                                                  }

                                           }

                                           if(jsonobj instanceof JSONObject) {

                                                  jsonarray.add(ttemp);

                                           }else {

                                                  jsonarray.add(jsonobj);

                                           }

                                    }

                                          num++;

                         }else {

                                       if(!(jsonobj instanceof JSONArray)) {

                                             

                                              jsonobj=((JSONObject)jsonobj).get(sourcePathNode.getName());

                                       }

                               

                                          Object ttemp=jsonClone(targettemp);

                                       Object array2=null;

                                       if(ttemp instanceof JSONObject) {

                                              array2=((JSONObject)ttemp).get(sourcePathNode.getName());

                                       }

                                    for(String key:lineMapping.getChildNodeId()) {

                                          

                                                  executForjsontojson(source,target,line.get(key),line,NodeUtil.FOR,parentTargettemp,array2,jsonobj,lineMapping,i,valuesNodeMap,functionMap);

                                                 

                                       }

                                    if(parentTargettemp!=null) {

                                           if (parentTargettemp instanceof JSONArray) {

                                                  if(num==0) {

                                                         ((JSONArray)parentTargettemp).clear();

                                                  }

                                                  ((JSONArray)parentTargettemp).add((ttemp));

                                           }else {

                                                 

                                           }

                                    }

                                          num++;

                         }

                           

                     }

           }

       }

             

      

      

}

    1. 执行

在菜单中能够点击执行来将源的格式转换成目标的格式。

JMenuItem exeItem;

                     exeItem = new JMenuItem("执行");

                     exeItem.addActionListener(new AbstractAction() {

                            /**

                             *

                             */

                            private static final long serialVersionUID = -1173970580445947956L;

                            public void actionPerformed(ActionEvent e) {

                                   String sourcepath=MapView.this.srcTree.getURI();

                                   String targetpath=MapView.this.dstTree.getURI();

                                   if(saveuri!=null) {

                                          if(MapperTree.sourceType.equals(NodeUtil.XML)&&MapperTree.targetType.equals(NodeUtil.XML)) {

                                                 lineMap.xmltoxml(saveuri, sourcepath, targetpath);

                                          }else if(MapperTree.sourceType.equals(NodeUtil.XML)&&MapperTree.targetType.equals(NodeUtil.JSON)) {

                                                 lineMap.xmltojson(saveuri, sourcepath, targetpath);

                                          }else if(MapperTree.sourceType.equals(NodeUtil.JSON)&&MapperTree.targetType.equals(NodeUtil.JSON)) {

                                                 lineMap.jsontojson(saveuri, sourcepath, targetpath);

                                          }else if(MapperTree.sourceType.equals(NodeUtil.JSON)&&MapperTree.targetType.equals(NodeUtil.XML)) {

                                                 lineMap.jsontoxml(saveuri, sourcepath, targetpath);

                                          }

                                   }

                                  

                            }

                     });

                     this.add(exeItem);

小结

在当今数字化转型加速的时代,数据格式的转换与映射已成为企业、科研机构和各类组织在数据处理过程中不可或缺的环节。通过开发这款基于Java的数据转换映射工具,我们成功解决了现有工具在功能、灵活性和易用性方面的不足。该工具结合了强大的技术库(如Dom4j和Fastjson)以及直观的图形化界面,实现了XML和JSON之间的高效转换与映射。

工具的核心功能包括支持多种数据格式的双向转换(XML到XML、JSON到JSON、XML到JSON以及JSON到XML)、树形结构的可视化展示、拖拽式的映射操作以及灵活的映射规则配置。这些功能不仅极大地简化了数据转换的复杂性,还降低了操作门槛,使得工具不仅适用于开发人员,也适合非技术背景的用户。

在实现过程中,我们通过精心设计的界面和底层逻辑,确保了工具的高效性、稳定性和扩展性。无论是处理简单的数据结构,还是复杂的嵌套对象和数组,工具都能通过用户定义的映射规则快速完成转换任务。此外,实时错误检测与调试功能进一步提升了用户体验,确保转换过程的准确性和可靠性。

通过这款工具,我们不仅为用户提供了高效的数据转换解决方案,还为企业的数字化转型和数据驱动的决策提供了有力支持。未来,我们将继续优化工具的功能,增加更多数据格式的支持,并进一步提升用户体验,以满足不断变化的市场需求。

相关文章:

图形化数据报文转换映射工具

目录 概要整体架构流程技术名词解释技术细节小结 概要 在当今数字化时代&#xff0c;数据的处理和分析是企业、科研机构以及各类组织日常运营的核心环节。数据来源广泛&#xff0c;格式多样&#xff0c;常见的数据格式包括XML&#xff08;可扩展标记语言&#xff09;和JSON&a…...

性能优化案例:通过合理设置spark.shuffle.memoryFraction参数的值来优化PySpark程序的性能

在PySpark中&#xff0c;合理调整spark.shuffle.memoryFraction参数可以有效优化Shuffle阶段的性能&#xff0c;尤其是在存在大量磁盘溢出的场景下。 通过合理设置spark.shuffle.memoryFraction并结合其他优化手段&#xff0c;可显著减少Shuffle阶段的磁盘I/O&#xff0c;提升P…...

[C]基础9.深入理解指针(1)

博客主页&#xff1a;算法歌者本篇专栏&#xff1a;[C]您的支持&#xff0c;是我的创作动力。 文章目录 0、总结1、内存和地址1.1 内存1.2 理解编址 2、指针变量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指针变量2.3 解引用操作符&#xff08;*&#xff09;2.4…...

网络模型简介:OSI七层模型与TCP/IP模型

计算机网络是现代信息社会的基石&#xff0c;而网络通信的基础在于理解网络模型。网络模型是对通信过程的抽象&#xff0c;它帮助我们理解数据从源到目的地的传输过程。常见的网络模型有 OSI 七层模型 和 TCP/IP 模型&#xff0c;这两种模型在理论和实践中都起着重要作用。 一、…...

第100+35步 ChatGPT学习:时间序列EMD-ARIMA-RF模型 vol. 2

基于Python 3.9版本演示 一、写在前面 上一节&#xff0c;我们学了EMD-ARIMA-RF模型去做预测。 这一节开始&#xff0c;我们尝试使用多项式回归矫正。 二、EMD&RF-ARIMA组合策略 该组合策略主要是将传统的经验模态分解&#xff08;EMD&#xff09;方法和现代的机器学习技…...

Adobe的AI生成3D数字人框架:从自拍到生动的3D化身

一、引言 随着人工智能技术的发展,我们见证了越来越多创新工具的出现,这些工具使得图像处理和视频编辑变得更加智能与高效。Adobe作为全球领先的创意软件公司,最近推出了一项令人瞩目的新技术——一个能够将普通的二维自拍照转换成栩栩如生的三维(3D)数字人的框架。这项技…...

2025美赛数学建模MCM/ICM选题建议与分析,思路+模型+代码

2025美赛数学建模MCM/ICM选题建议与分析,思路模型代码&#xff0c;详细更新见文末名片 一、问题A&#xff1a;测试时间&#xff1a;楼梯的恒定磨损&#xff08;Archaeological Modeling&#xff09; 适合专业&#xff1a;考古学、历史学、数学、机械工程 难度&#xff1a;中等…...

golang中的包管理-上--简介

‌Go语言中的包&#xff08;Package&#xff09;是组织和管理代码的基本单元&#xff0c;通过合理地使用包&#xff0c;可以提高代码的复用性、可维护性和可读性。 包的基本概念和定义 在Go语言中&#xff0c;每个源代码文件都属于一个包。包的声明位于文件的最顶部&#xff…...

深入了解 HTTP 头部中的 Accept-Encoding:gzip、deflate、br、zstd

在现代Web开发中&#xff0c;性能优化是至关重要的一部分。HTTP协议中的Accept-Encoding头部正是为性能提升提供了一个非常有效的方式&#xff0c;它告知服务器客户端能够理解并接收哪些压缩算法的响应内容。在这篇博客中&#xff0c;我们将详细探讨Accept-Encoding头部的作用&…...

QModbusTCPClient 服务器断开引起的程序崩溃

最近使用QModbusTCPClient 与一套设备通信&#xff0c;有一个QTimer频繁的通过读取设备寄存器。程序运行良好&#xff0c;但是有个问题&#xff1a;正常进行中设备断电了&#xff0c;整个程序都会崩溃。解决过程如下&#xff1a; 1.失败方案一 在QModbusTCPClient的errorOccu…...

Unity|小游戏复刻|见缝插针2(C#)

控制针的运动 新建一个Pin脚本 将Pin脚本拖到针Pin的下面 保存代码 using UnityEngine;public class Pin : MonoBehaviour {public float speed 5;private bool isFly false;private bool isReach false;private Transform startPosition;// Start is called once bef…...

数据结构——堆(C语言)

基本概念&#xff1a; 1、完全二叉树&#xff1a;若二叉树的深度为h&#xff0c;则除第h层外&#xff0c;其他层的结点全部达到最大值&#xff0c;且第h层的所有结点都集中在左子树。 2、满二叉树&#xff1a;满二叉树是一种特殊的的完全二叉树&#xff0c;所有层的结点都是最…...

ML基础2-python中的可视化1:matplotlib

承接我的上一篇博客&#xff1a; https://blog.csdn.net/weixin_62528784/article/details/145329298?spm1001.2014.3001.5501 在机器学习的过程中&#xff0c;我们需要掌握大量的Python包&#xff0c;常用的有pandas和numpy这些基本数据管理的包(在后续更新中我会讲解)与mat…...

SpringBoot--基本使用(配置、整合SpringMVC、Druid、Mybatis、基础特性)

这里写目录标题 一.介绍1.为什么依赖不需要写版本&#xff1f;2.启动器(Starter)是何方神圣&#xff1f;3.SpringBootApplication注解的功效&#xff1f;4.启动源码5.如何学好SpringBoot 二.SpringBoot3配置文件2.1属性配置文件使用2.2 YAML配置文件使用2.3 YAML配置文件使用2.…...

9.C++文件与流

C文件与流 在 C 中&#xff0c;文件和流是用于处理输入输出操作的重要概念&#xff0c;以下是关于它们的详细讲解&#xff1a; 流的概念 定义&#xff1a;流是一种抽象概念&#xff0c;它代表了数据的序列。在 C 中&#xff0c;流可以是输入流&#xff08;从外部源如文件或键…...

CSRF 跨站请求伪造漏洞

原理 当一个网站A使用Cookie&#xff0c;存储Session或Token来用于单点登录和权限操作时。浏览器将Cookie存储到浏览器中。当用户在访问另一个网站V时&#xff0c;黑客可以通过伪造表单&#xff0c;向网站A发送修改重要信息(如密码)、支付等操作&#xff0c;浏览器会自动携带C…...

从ABCD谈人工智能对软件开发的影响(2)

接“造词圈子割韭菜”-从ABCD谈人工智能对软件开发的影响&#xff08;1&#xff09; &#xff08;六&#xff09;分步解析之二&#xff1a;组织价值&#xff08;业务用例图&#xff09; 这一步本来建模难度也只有&#xff0c;AI的助力分数可以做到30分。 ★很多领域驱动设计…...

我谈《概率论与数理统计》的知识体系

学习《概率论与数理统计》二十多年后&#xff0c;在廖老师的指导下&#xff0c;才厘清了各章之间的关系。首先&#xff0c;这是两个学科综合的一门课程&#xff0c;这一门课程中还有术语冲突的问题。这一门课程一条线两个分支&#xff0c;脉络很清晰。 概率论与统计学 概率论…...

第 10 课 Python 内置函数

1. 什么是内置函数 Python解释器也是一个程序,它给用户提供了一些常用功能,并给它们起了独一无二的名字,这些常用功能就是内置函数。Python解释器启动以后,内置函数也生效了,可以直接拿来使用。 内置函数是解释器的一部分,它随着解释器的启动而生效;标准库函数是…...

MySQL中的读锁与写锁:概念与作用深度剖析

MySQL中的读锁与写锁&#xff1a;概念与作用深度剖析 在MySQL数据库的并发控制机制中&#xff0c;读锁和写锁起着至关重要的作用。它们是确保数据在多用户环境下能够正确、安全地被访问和修改的关键工具。 一、读锁&#xff08;共享锁&#xff09;概念 读锁&#xff0c;也称为…...

Kotlin Bytedeco OpenCV 图像图像50 仿射变换 图像缩放

Kotlin Bytedeco OpenCV 图像图像50 仿射变换 图像缩放 1 添加依赖2 测试代码3 测试结果 在OpenCV中&#xff0c;仿射变换&#xff08;Affine Transformation&#xff09;和透视变换&#xff08;Perspective Transformation&#xff09;是两种常用的图像几何变换方法。 变换方…...

导出地图为图像文件

使用函数可以将地图或布局视图的内容导出为图像文件. 操作方法: 1.打开目标地图文档 2.导入arcpy.mapping模块 import arcpy.mapping as mapping 3.引用当前活动地图文档,把该引用赋值给变量 mxd mapping.MapDocument() 4.获取地图文档中的数据框列表,查找目标数据框,并…...

【Linux】命令为桥,存在为岸,穿越虚拟世界的哲学之道

文章目录 Linux基础入门&#xff1a;探索操作系统的内核与命令一、Linux背景与发展历史1.1 Linux的起源与发展1.2 Linux与Windows的对比 二、Linux的常用命令2.1 ls命令 - "List"&#xff08;列出文件)2.2 pwd命令 - "Print Working Directory"&#xff08…...

如何在gitee/github上面搭建obsidian的图床

在搭建图床之前我们需要知道图床是一个什么东西,图床顾名思义就是存放图片的地方&#xff0c;那么我们为什么要搭建图床呢&#xff1f;因为我们在写博客的时候&#xff0c;很多同学都是在本地使用typora或者是obsidian进行markdown语法的文章的书写&#xff0c;文件格式通常都是…...

【DIY小记】减肥10kg保持半年的经验分享

作为程序员&#xff0c;脑力劳动者&#xff0c;保持一个健康的身体&#xff0c;是非常重要的。回顾24年自己取得的结果&#xff0c;一个比较亮眼的就是减肥减了10kg&#xff0c;到达了一个比较健康的体重&#xff0c;保持了半年没有反弹&#xff0c;当然到现在也依然在保持。今…...

[STM32 - 野火] - - - 固件库学习笔记 - - -十一.电源管理系统

一、电源管理系统简介 电源管理系统是STM32硬件设计和系统运行的基础&#xff0c;它不仅为芯片本身提供稳定的电源&#xff0c;还通过多种电源管理功能优化功耗、延长电池寿命&#xff0c;并确保系统的可靠性和稳定性。 二、电源监控器 作用&#xff1a;保证STM32芯片工作在…...

C# 探秘:PDFiumCore 开启PDF读取魔法之旅

一、引言 在当今数字化时代&#xff0c;PDF 文件就像一个个神秘的宝盒&#xff0c;里面装满了各种信息。无论是项目文档、学术论文还是产品说明书&#xff0c;PDF 格式凭借其良好的兼容性和稳定性&#xff0c;成为了信息传递的重要载体。想象一下&#xff0c;你接到一个紧急任…...

计算机网络-运输层

重点内容&#xff1a; 运输层 是整个网络体系结构中的关键层次之一。一定要弄清以下一些重要概念&#xff1a; (1) 运输层为相互通信的应用进程提供逻辑通信。 (2) 端口和套接字的意义。 (3) 无连接的 UDP 的特点。 (4) 面向连接的 TCP 的特点。 (5) 在不可靠的网…...

TLF35584 基本介绍

1 概述 1&#xff09;多电压电源芯片&#xff0c;包含6路输出电压。 LDO_Com&#xff1a;低降后调节器 5V/200mA 通信电源。LDO_C &#xff1a;低降后调节器 5V/600mA (TLF35584xxVS1)/3.3 V/600mA (TLF35584xxVS2) uC电源。Volt_Ref &#xff1a;参考电压5.0 V /- 1%/150mA …...

【Python】第四弹---深入理解Python控制流:从顺序到循环的全面解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、顺序语句 2、条件语句 2.1、什么是条件语句 2.2、语法格式 2.3、缩进和代码块 2.4、练习 2.5、空…...

PBFT算法

在我的博客中对于RAFT算法也有详细的介绍&#xff0c;raft算法包含三种角色&#xff0c;分别是&#xff1a;跟随者&#xff08; follower &#xff09;&#xff0c;候选人&#xff08;candidate &#xff09;和领导者&#xff08; leader &#xff09;。集群中的一个节点在某一…...

软件过程模型

软件过程概念 软件生命周期 软件过程 在工作产品构建过程中&#xff0c;所需完成的工作活动&#xff0c;动作和任务的集合。 软件过程模型 软件过程评估 能力成熟度模型&#xff08;CMM&#xff09; 传统软件过程模型 瀑布模型&#xff08;第一个软件过程模型&#xff…...

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …...

代码随想录算法【Day31】

Day31 56. 合并区间 class Solution { public://按照左边界&#xff0c;从小到大排序static bool cmp(const vector<int>& a, const vector<int>& b){return a[0] < b[0];} ​vector<vector<int>> merge(vector<vector<int>>…...

Apache Tomcat文件包含漏洞复现(详细教程)

1.漏洞原理 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;其安装后会默认开启ajp连接器&#xff0c;方便与其他web服务器通过ajp协议进行交互。属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发…...

C#高级:常用的扩展方法大全

1.String public static class StringExtensions {/// <summary>/// 字符串转List&#xff08;中逗 英逗分隔&#xff09;/// </summary>public static List<string> SplitCommaToList(this string data){if (string.IsNullOrEmpty(data)){return new List&…...

麒麟操作系统基础知识保姆级教程(二十一)进入单用户模式

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 在咱们运维工作中&#xff0c;服务器的密码长度&#xff0c;密码复杂度&#xff0c;修改时间&#xff0c;超时时间&#xff0c;用户权限管理&#xff0c;root直接远程连接&#xff0c;普通用户su到r…...

基于C语言的数组从入门到精通

简介:本篇文章主要介绍了一维数组,二维数组,字符数组的定义,数组的应用,数组的核心代码解析,适用于0基础的初学者. C语言数组 1.一维数组 1.1定义 1.1.1声明 语法:数据类型 数组名[数组大小];示例:int arr[5]; 1.1.2初始化 a.静态初始化 完全初始化&#xff1a;int arr[5] {1…...

CLOUDFLARE代理请求重定向你太多次

现象 使用CLOUDFLARE代理前请求正常&#xff0c;使用CLOUDFLARE代理请求后出现 原因分析 以下是我的猜测&#xff0c;在默认情况下 CLOUDFLARE代理&#xff0c;可能是直接请求我们服务器的IP&#xff0c;比如&#xff1a;http://1.1.1.1 而不是通过域名的方式&#xff08;如…...

算法随笔_21:字符的最短距离

上一篇:算法随笔_20:区间子数组个数 -CSDN博客 题目描述如下: 给你一个字符串 s 和一个字符 c &#xff0c;且 c 是 s 中出现过的字符。 返回一个整数数组 answer &#xff0c;其中 answer.length s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。 …...

第19个项目:蛇年特别版贪吃蛇H5小游戏

下载地址:https://download.csdn.net/download/mosquito_lover1/90308956 游戏玩法: 点击"开始游戏"按钮开始 使用键盘方向键控制蛇的移动 吃到红色食物可以得分 撞到墙壁或自己会结束游戏 核心源码: class SnakeGame { constructor() { this.canvas = docum…...

Vue3 30天精进之旅:Day01 - 初识Vue.js的奇妙世界

引言 在前端开发领域&#xff0c;Vue.js是一款极具人气的JavaScript框架。它以其简单易用、灵活高效的特性&#xff0c;吸引了大量开发者。本文是“Vue 3之30天系列学习”的第一篇博客&#xff0c;旨在帮助大家快速了解Vue.js的基本概念和核心特性&#xff0c;为后续的深入学习…...

单值二叉树(C语言详解版)

一、摘要 今天要讲的是leetcode单值二叉树&#xff0c;这里用到的C语言&#xff0c;主要提供的是思路&#xff0c;大家看了我的思路之后可以点击链接自己试一下。 二、题目简介 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单…...

贵州端午黔粽探源:贵州味道与黔味文化与糯米的融合?

黔粽的由来? 黔粽的贵州味道?探索贵州“黔味文化”找寻答案! 黔粽的特色由来与贵州味道 贵州粽,简称黔粽。黔粽的主要特色是“酸辣”,以其独特的“酸辣”口味和地域特色,与浙粽、京粽、粤粽、川粽、云粽、闽粽、台湾粽并列为“全国八大粽子派别”之一,并与甜味粽、咸味粽共…...

【Project】CupFox电影网站数据爬取分析与可视化

数据采集清洗与数据存储流程如下图所示。 数据分析与数据可视化流程设计如下 1.使用pymongo从数据库中查询所需的数据。对数据进行处理和分析&#xff0c;进行统计、分类、聚合等操作&#xff0c;提取关键指标和洞察。分析结果可以通过编写Python代码进一步优化、筛选和整理&a…...

Spring Boot 后端跨域解决方案:解锁前后端通信的障碍

随着前后端分离架构的普及&#xff0c;跨域资源共享&#xff08;Cross-Origin Resource Sharing, CORS&#xff09;问题成为了许多开发者必须面对的一个挑战。当Web浏览器尝试从一个源加载资源到另一个不同的源时&#xff0c;出于安全考虑&#xff0c;它会实施同源策略&#xf…...

Linux如何设置用户登录超时(/etc/profile)

Linux如何设置用户登录超时(/etc/profile) 1. 针对所有用户 # vi /etc/profile ... export TMOUT900 # 设置闲置时间为15分钟&#xff0c;单位为秒;如果没有此行则直接添加进去 ... vi /etc/profile TMOUT18000000000000 export QT_IM_MODULEfcitx readonly TMOUT expor…...

Elastic Cloud Serverless 获得主要合规认证

作者&#xff1a;来自 Elastic Oliver Mao 我们很高兴地宣布&#xff0c;Elastic Cloud Serverless 已获得多项重要的合规性认证。这一里程碑加强了我们对安全性、隐私性和法规遵从性的承诺。Elastic Cloud Serverless 现已通过以下行业领先框架的审核或认证&#xff1a;SOC 2 …...

渐变颜色怎么调?

渐变颜色的调整是设计中非常重要的一部分&#xff0c;尤其是在创建具有视觉吸引力和深度感的设计作品时。以下是一些在不同设计软件中调整渐变颜色的详细步骤和技巧&#xff1a; 一、Adobe Photoshop 1. 创建渐变 打开渐变工具&#xff1a; 选择工具栏中的“渐变工具”&#x…...

DDD该怎么去落地实现(1)关键是“关系”

DDD落地的关键是“关系” 这些年&#xff0c;我认为DDD走到了一个死胡同里了&#xff0c;因为落地实现过于困难。很多团队在经过一段时间的学习&#xff0c;清楚理解了DDD那些晦涩的概念&#xff0c;根据业务绘制出领域模型&#xff0c;这都不困难。但绘制领域模型不是我们最终…...