在DataWeave中递归遍历和展平JSON对象 [英] Recursivly traverse and flatten JSON object in DataWeave

查看:73
本文介绍了在DataWeave中递归遍历和展平JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想遍历并展平一个具有以下结构的大JSON文件,该结构显示了产品层次结构(将其视为在线商店中的导航):

I want to traverse and flatten a big JSON file that has following structure showing a product hierarchie (think of it as navigation in an online shop):

productGroups: [
    {
        "key": "child 1"
        ...
        "childrenProductGroups": [
            {
                "key": "child 1.1",
                ...,
                "childrenProductGroups": []
            },
            {
                "key": "child 1.2"
                ...
                "childrenProductGroups": [
                    {
                        "key": "child 1.2.1",
                        ...,
                        "childrenProductGroups": [
                            {
                                "key": "child 1.2.1.1",
                                ...,
                                childrenProductGroups": [
                                    ...
                                ]
                            }
                        ]
                    },
                    {
                        "key": "child 1.2.2",
                        ...,
                        "childrenProductGroups": []
                    }
                ]
                
            },
            {
                "key": "child 1.3",
                ...,
                "childrenProductGroups": [
                    ...
                ]
            }
        ]
    }, 
    {
        "key": "child 2",
        ...,
        "childrenProductGroups": [
            ...
        ]
    },
    {
        "key": "child 3",
        ...,
        "childrenProductGroups": [
            ...
        ]
    }
]

我想用以下格式展平它们:

And I want to flatten them in a format like this:

{
    "hierarchieSet": [
        {
            "Nodeid": "00000001", # Number in this json
            "Nodename": "child 1",
            "Tlevel": "01", # First child of product group
            "Parentid": "00000000", # Parent is null
            "Childid": "00000002", # Child node number
            "Nextid": "00000008" # Node number on the same level (child 2)
        }, 
        {
            "Nodeid": "00000002",
            "Nodename": "child 1.1",
            "Tlevel": "02",
            "Parentid": "00000001",
            "Childid": "00000003",
            "Nextid": "00000003"
        }, 
        {
            "Nodeid": "00000003",
            "Nodename": "child 1.2",
            "Tlevel": "02",
            "Parentid": "00000002",
            "Childid": "00000005",
            "Nextid": "00000007"
        }, 
        {
            "Nodeid": "00000004",
            "Nodename": "child 1.2.1",
            "Tlevel": "03",
            "Parentid": "00000003",
            "Childid": "0000005",
            "Nextid": "00000006"
        }
        , 
        {
            "Nodeid": "00000005",
            "Nodename": "child 1.2.1.1",
            "Tlevel": "04",
            "Parentid": "00000004",
            "Childid": "0000000", #No more children
            "Nextid": "00000000"
        }, 
        {
            "Nodeid": "00000006",
            "Nodename": "child 1.2.2",
            "Tlevel": "03",
            "Parentid": "00000003",
            "Childid": "0000000",
            "Nextid": "00000000"
        }, 
        {
            "Nodeid": "00000007",
            "Nodename": "child 1.3",
            "Tlevel": "02",
            "Parentid": "00000001",
            "Childid": "0000000",
            "Nextid": "00000000"
        }, 
        {
            "Nodeid": "00000008",
            "Nodename": "child 2",
            "Tlevel": "01",
            "Parentid": "00000000",
            "Childid": "0000009", # 00000009 not shown
            "Nextid": "00000014" # 
        }, 
        ...
        {
            "Nodeid": "000000014",
            "Nodename": "child 3",
            "Tlevel": "01",
            "Parentid": "00000000",
            "Childid": "00000015",
            "Nextid": "00000000" # 00000010 does not exist
        }
    ]
}

因此,我已经确定了一些主要问题:

Thus I have identified some main concerns:

  • 树结构的递归
  • 转换元素
  • 使结构平整
  • 跟踪父母,兄弟姐妹和孩子
  • 跟踪递归级别
  • 格式化数字

我试图通过2种不同的方法来解决这个问题:

I tried to solve this issue by 2 different approaches:

  • 使用DataWeave转换所有元素
  • 使用Java遍历结构

由于我对函数式编程还很陌生,所以我更加关注Java实现,但遇到了许多问题.

As I'm fairly new to functional programming I put more focus on the Java implementation but ran into a number of issues.

Java方法

阅读json>初始化Tree var并分配Java实例>对于顶级数组中的每个元素,请调用 Tree.java 中的 traverse(data,level).
Tree.java:

Java approach

Read json > Init Tree var and assign the Java instance > for each element in top-level array invoke traverse(data, level) in Tree.java.
Tree.java:

import org.json.JSONObject;

public class Tree {
    private int id = 0;
    private List<Node> nodes = new ArrayList<Node>();
    
    public Tree() {
        nodes.add(new Node("01", "00000001", "HOME", "01", "00000000", "00000002", "00000000"));
    }
    
    public void traverse(String data, int level) {
        System.out.println(data);
        // TODO parse json
    }
    
    private void visit(JSONObject parent, JSONObject node, int level) {
        id++;
        nodes.add(new Node("01", String.valueOf(id), node.getString("key"), String.valueOf(level), "", "", ""));
    }
    
    public List<Node> getNodes() {
        return nodes;
    }

    private static class Node {
        private String zshop, nodename, parentid, childid, nextid, nodeid, tlevel;
        
        public Node(String zshop, String nodeid, String nodename, String tlevel, String parentid, String childid, String nextid) {
            this.zshop = zshop;
            this.nodeid = nodeid;
            this.nodename = nodename;
            this.tlevel = tlevel;
            this.parentid = parentid;
            this.childid = childid;
            this.nextid = nextid;
        }
    }
}

在调用invoke操作时,我使用以下有效负载:

When calling the invoke action I use this payload:

%dw 2.0
output application/java
---
{
    data: vars.rootMessage.payload as String,
    level: 1
}

但这会产生以下错误:

"不能强制对象{编码:UTF-8,mediaType:text/json;charset = UTF-8,mimeType:文本/json,原始:org.mule.weave.v2.el.SeekableCursorStream@50ecee52}(org.mule.weave.v2.el.MuleTypedValue@511ba9cc)转换为字符串

"Cannot coerce Object { encoding: UTF-8, mediaType: text/json; charset=UTF-8, mimeType: text/json, raw: org.mule.weave.v2.el.SeekableCursorStream@50ecee52 } (org.mule.weave.v2.el.MuleTypedValue@511ba9cc) to String

5 |数据:vars.rootMessage.payload as String,^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Trace:at main(line:5,column:7)"评估表达式:%dw 2.0输出应用程序/java--- {data:vars.rootMessage.payload as String,level:1}.

5| data: vars.rootMessage.payload as String, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Trace: at main (line: 5, column: 7)" evaluating expression: "%dw 2.0 output application/java --- { data: vars.rootMessage.payload as String, level: 1 }".

我尝试了很多事情:

  • 将其投射到我用Java语言编写的 ProductGroup 对象中
  • 尝试将检索到的对象强制转换为 org.json.JSONObject
  • 尝试缓冲并读取 vars.rootMessage.payload(二进制)

但是我无法解决所有这些问题.

But I wasn't able to solve it with any of these issues.

DataWeave方法我的.dw脚本

%dw 2.0
fun append
(item: Object, acc: Object = {
}) = acc ++ item

fun mapper(item: Object) = 
{
    Zshop: "01",
    Nodeid: "00000000",
    Nodename: item.key as Number as String {format: ""},
    Tlevel: "02",
    Parentid: "00000000",
    Childid: "00000000",
    Nextid: "00000000"
}
    
fun traverse(a: Array, level: Number) = 
    a map $ flatMap(value, index) -> value
    
output application/json
---
{
    test: payload.productGroups reduce (item, acc) -> append(mapper(item), acc)
}

我尝试解决其中一些问题的地方. mapper(item)应该创建json对象,我可以使用 appender(item,acc)将其附加到最终输出中.递归已草绘,但不是我主要关心的问题.

Where I tried to solve some of the problems. mapper(item) should create json objects that I can append to the final output with appender(item, acc). Recursion has been sketched, but is not my main concern yet.

这将产生以下结果:

(original payload),
"Zshop": "01",
"Nodeid": "00000000",
"Nodename": "800",
"Tlevel": "02",
"Parentid": "00000000",
"Childid": "00000000",
"Nextid": "00000000",
"Zshop": "01",
"Nodeid": "00000000",
"Nodename": "110",
"Tlevel": "02",
"Parentid": "00000000",
"Childid": "00000000",
"Nextid": "00000000",
"Zshop": "01",
"Nodeid": "00000000",
"Nodename": "720",
"Tlevel": "02",
"Parentid": "00000000",
"Childid": "00000000",
"Nextid": "00000000",
"Zshop": "01",
"Nodeid": "00000000",
"Nodename": "710",
"Tlevel": "02",
"Parentid": "00000000",
"Childid": "00000000",
"Nextid": "00000000",
...

我想知道为什么我在没有任何对象结构的情况下获得平坦的结果.

我的问题:

Where I wonder why I'm getting a flat result without any object structure.

My questions:

  • Java:为什么我不能转换字符串或它如何正确完成
  • DataWeave:有没有我看不到的简单解决方案?
  • 为什么它是平坦的结果而不是对象?
  • reduce flatMap 函数的用法是否为此正确?
  • Java: Why can't I cast the String or how is it done properly
  • DataWeave: Is there an easy solution I don't see?
  • Why is it a flat result and not an object?
  • Are the usages of the reduce and flatMap functions correct for this purpose?

欢迎任何帮助和/或反馈.

Any help and / or feedback is welcome.

推荐答案

Java:为什么我不能转换字符串或如何正确完成

Java: Why can't I cast the String or how is it done properly

JSON不是字符串.使用write(payload,'application/json')具有字符串.

JSON is not String. Use write(payload,'application/json') to have String.

DataWeave:有没有一个简单的解决方案,我看不到?

DataWeave: Is there an easy solution I don't see?

只需传递对象,它就是Java中的Map.由于它是树-每个分支都是该Map内的另一个Map.

Just pass the object, It is Map in Java. Since it is tree - each branch is another Map inside this Map.

为什么它是平坦的结果而不是对象?

Why is it a flat result and not an object?

它始终是对象.Java世界中没有其他东西.

It is ALWAYS Object. There are no other things in Java world.

reduce和flatMap函数的用法是否为此正确?

Are the usages of the reduce and flatMap functions correct for this purpose?

不.mapObject和递归应该是很好的方法.

No. mapObject and recursion should be good approach.

这篇关于在DataWeave中递归遍历和展平JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆