为了账号安全,请及时绑定邮箱和手机立即绑定

在java中展平三层嵌套的JSON字符串

在java中展平三层嵌套的JSON字符串

Cats萌萌 2023-08-09 14:54:51
要求是为输入 JSON 对象创建一个通用的扁平化实用程序以扁平化 JSON 对象。示例 JSON 如下所示{  "Source": "source-1",  "Rows": [    {      "Keys": {        "device-id": "BC04-EBH-N3K-01",        "interface-name": "TenGigE0/0/0/39",        "node-name": "0/0/CPU0"      },      "Timestamp": 1567621527656,      "inner": {        "donm": {          "id": "0062",          "mol": {            "rem": 30,            "len": 11,            "org": {              "ldp": [                {                  "t": 486,                  "o": 322                },                {                  "t": 487,                  "o": 32,                  "twss": 1,                  "tlv": "00:01"                }              ]            },            "chlen": 14,            "poe": 5,            "combs": 10,            "chaype": 4,            "rek": 0,            "rem-um": 67          },          "detail": {            "enas": "B,R",            "systes": "B,R",            "timng": 91,            "syn": "C",            "met-type": 0,            "neses": {              "lldEDIT": [                {                  "ium": 830,                  "m": 1,                  "ass": {                    "ape": "ipv4",                    "ipvs": "94"                  }                }              ]            },            "pess": "0008",            "por]d": 0,            "pon": "BCtive",            "sysme": "BC1"          },          "reme": "Bu1",          "hean": 0,          "porl": "Et1"        }      }    }  ],  "Tey": {    "epath": "Cgetail",    "sustr": "MX",    "coime": 1567621527653,    "msp": 1567621527653,    "come": 1567621527660,    "nor": "BC5",    "cid": 14789654  }}我一直在尝试将其扁平化为 3 个级别,并提出了以下实用程序。但是,当我必须处理数组和 String、long、Timestamp 等类型的值时,事情变得复杂。此外,我无法理解如何维护嵌套键的唯一性。任何帮助是极大的赞赏。
查看完整描述

4 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

您可以查看json-flattener。


查看完整回答
反对 回复 2023-08-09
?
慕哥9229398

TA贡献1877条经验 获得超6个赞

为了避免与键名称冲突,您可以使用JSON 指针规范来创建它们。它也受到Jackson库的支持,因此您可以稍后使用它们来遍历JsonNode节点。

简单的实现如下所示:

import com.fasterxml.jackson.databind.JsonNode;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.node.ArrayNode;

import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.File;

import java.util.LinkedHashMap;

import java.util.Map;

import java.util.Objects;

import java.util.concurrent.atomic.AtomicInteger;


public class JsonApp {


  public static void main(String[] args) throws Exception {

    File jsonFile = new File("./test.json");


    ObjectMapper mapper = new ObjectMapper();

    JsonNode root = mapper.readTree(jsonFile);

    Map<String, JsonNode> map = new JsonFlattener(root).flatten();


    System.out.println("Use key-value pairs:");

    map.forEach(

        (k, v) -> {

          System.out.println(k + " => " + v);

        });


    System.out.println();

    System.out.println("Use pointers:");

    map.forEach(

        (k, v) -> {

          System.out.println(k + " => " + root.at(k));

        });

  }

}


class JsonFlattener {


  private final Map<String, JsonNode> json = new LinkedHashMap<>(64);

  private final JsonNode root;


  JsonFlattener(JsonNode node) {

    this.root = Objects.requireNonNull(node);

  }


  public Map<String, JsonNode> flatten() {

    process(root, "");

    return json;

  }


  private void process(JsonNode node, String prefix) {

    if (node.isObject()) {

      ObjectNode object = (ObjectNode) node;

      object

          .fields()

          .forEachRemaining(

              entry -> {

                  process(entry.getValue(), prefix + "/" + entry.getKey());

              });

    } else if (node.isArray()) {

      ArrayNode array = (ArrayNode) node;

      AtomicInteger counter = new AtomicInteger();

      array

          .elements()

          .forEachRemaining(

              item -> {

                process(item, prefix + "/" + counter.getAndIncrement());

              });

    } else {

      json.put(prefix, node);

    }

  }

}

上面的代码打印:


Use key-value pairs:

/Source => "source-1"

/Rows/0/Keys/device-id => "BC04-EBH-N3K-01"

/Rows/0/Keys/interface-name => "TenGigE0/0/0/39"

/Rows/0/Keys/node-name => "0/0/CPU0"

/Rows/0/Timestamp => 1567621527656

/Rows/0/inner/donm/id => "0062"

/Rows/0/inner/donm/mol/rem => 30

/Rows/0/inner/donm/mol/len => 11

/Rows/0/inner/donm/mol/org/ldp/0/t => 486

/Rows/0/inner/donm/mol/org/ldp/0/o => 322

/Rows/0/inner/donm/mol/org/ldp/1/t => 487

/Rows/0/inner/donm/mol/org/ldp/1/o => 32

/Rows/0/inner/donm/mol/org/ldp/1/twss => 1

/Rows/0/inner/donm/mol/org/ldp/1/tlv => "00:01"

/Rows/0/inner/donm/mol/chlen => 14

/Rows/0/inner/donm/mol/poe => 5

/Rows/0/inner/donm/mol/combs => 10

/Rows/0/inner/donm/mol/chaype => 4

/Rows/0/inner/donm/mol/rek => 0

/Rows/0/inner/donm/mol/rem-um => 67

/Rows/0/inner/donm/detail/enas => "B,R"

/Rows/0/inner/donm/detail/systes => "B,R"

/Rows/0/inner/donm/detail/timng => 91

/Rows/0/inner/donm/detail/syn => "C"

/Rows/0/inner/donm/detail/met-type => 0

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ium => 830

/Rows/0/inner/donm/detail/neses/lldEDIT/0/m => 1

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ass/ape => "ipv4"

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ass/ipvs => "94"

/Rows/0/inner/donm/detail/pess => "0008"

/Rows/0/inner/donm/detail/por]d => 0

/Rows/0/inner/donm/detail/pon => "BCtive"

/Rows/0/inner/donm/detail/sysme => "BC1"

/Rows/0/inner/donm/reme => "Bu1"

/Rows/0/inner/donm/hean => 0

/Rows/0/inner/donm/porl => "Et1"

/Tey/epath => "Cgetail"

/Tey/sustr => "MX"

/Tey/coime => 1567621527653

/Tey/msp => 1567621527653

/Tey/come => 1567621527660

/Tey/nor => "BC5"

/Tey/cid => 14789654


Use pointers:

/Source => "source-1"

/Rows/0/Keys/device-id => "BC04-EBH-N3K-01"

/Rows/0/Keys/interface-name => "TenGigE0/0/0/39"

/Rows/0/Keys/node-name => "0/0/CPU0"

/Rows/0/Timestamp => 1567621527656

/Rows/0/inner/donm/id => "0062"

/Rows/0/inner/donm/mol/rem => 30

/Rows/0/inner/donm/mol/len => 11

/Rows/0/inner/donm/mol/org/ldp/0/t => 486

/Rows/0/inner/donm/mol/org/ldp/0/o => 322

/Rows/0/inner/donm/mol/org/ldp/1/t => 487

/Rows/0/inner/donm/mol/org/ldp/1/o => 32

/Rows/0/inner/donm/mol/org/ldp/1/twss => 1

/Rows/0/inner/donm/mol/org/ldp/1/tlv => "00:01"

/Rows/0/inner/donm/mol/chlen => 14

/Rows/0/inner/donm/mol/poe => 5

/Rows/0/inner/donm/mol/combs => 10

/Rows/0/inner/donm/mol/chaype => 4

/Rows/0/inner/donm/mol/rek => 0

/Rows/0/inner/donm/mol/rem-um => 67

/Rows/0/inner/donm/detail/enas => "B,R"

/Rows/0/inner/donm/detail/systes => "B,R"

/Rows/0/inner/donm/detail/timng => 91

/Rows/0/inner/donm/detail/syn => "C"

/Rows/0/inner/donm/detail/met-type => 0

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ium => 830

/Rows/0/inner/donm/detail/neses/lldEDIT/0/m => 1

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ass/ape => "ipv4"

/Rows/0/inner/donm/detail/neses/lldEDIT/0/ass/ipvs => "94"

/Rows/0/inner/donm/detail/pess => "0008"

/Rows/0/inner/donm/detail/por]d => 0

/Rows/0/inner/donm/detail/pon => "BCtive"

/Rows/0/inner/donm/detail/sysme => "BC1"

/Rows/0/inner/donm/reme => "Bu1"

/Rows/0/inner/donm/hean => 0

/Rows/0/inner/donm/porl => "Et1"

/Tey/epath => "Cgetail"

/Tey/sustr => "MX"

/Tey/coime => 1567621527653

/Tey/msp => 1567621527653

/Tey/come => 1567621527660

/Tey/nor => "BC5"

/Tey/cid => 14789654



查看完整回答
反对 回复 2023-08-09
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

试试这个代码:


public static void flattenJson(JsonNode node, String parent, Map<String, ValueNode> map) {

    if (node instanceof ValueNode) {

        map.put(parent, (ValueNode)node);

    } else {

        String prefix = parent == null ? "" : parent + ".";

        if (node instanceof ArrayNode) {

            ArrayNode arrayNode = (ArrayNode)node;

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

                flattenJson(arrayNode.get(i), prefix + i, map);

            }

        } else if (node instanceof ObjectNode) {

            ObjectNode objectNode = (ObjectNode) node;

            for (Iterator<Map.Entry<String, JsonNode>> it = objectNode.fields(); it.hasNext(); ) {

                Map.Entry<String, JsonNode> field = it.next();

                flattenJson(field.getValue(), prefix + field.getKey(), map);

            }

        } else {

            throw new RuntimeException("unknown json node");

        }

    }

}


public static Map<String, ValueNode> flattenJson(JsonNode input) {

    Map<String, ValueNode> map = new LinkedHashMap<>();

    flattenJson(input, null, map);

    return map;

}

然后你可以打电话


    ObjectMapper om = new ObjectMapper();

    JsonNode jsonNode = om.readTree(json);

    Map<String, ValueNode> m = flattenJson(jsonNode);

    for (Map.Entry<String, ValueNode> kv : m.entrySet()) {

        System.out.println(kv.getKey() + "=" + kv.getValue().asText());

    }

输出:


Source=source-1

Rows.0.Keys.device-id=BC04-EBH-N3K-01

Rows.0.Keys.interface-name=TenGigE0/0/0/39

Rows.0.Keys.node-name=0/0/CPU0

Rows.0.Timestamp=1567621527656

Rows.0.inner.donm.id=0062

Rows.0.inner.donm.mol.rem=30

Rows.0.inner.donm.mol.len=11

Rows.0.inner.donm.mol.org.ldp.0.t=486

Rows.0.inner.donm.mol.org.ldp.0.o=322

Rows.0.inner.donm.mol.org.ldp.1.t=487

Rows.0.inner.donm.mol.org.ldp.1.o=32

Rows.0.inner.donm.mol.org.ldp.1.twss=1

Rows.0.inner.donm.mol.org.ldp.1.tlv=00:01

Rows.0.inner.donm.mol.chlen=14

Rows.0.inner.donm.mol.poe=5

Rows.0.inner.donm.mol.combs=10

Rows.0.inner.donm.mol.chaype=4

Rows.0.inner.donm.mol.rek=0

Rows.0.inner.donm.mol.rem-um=67

Rows.0.inner.donm.detail.enas=B,R

Rows.0.inner.donm.detail.systes=B,R

Rows.0.inner.donm.detail.timng=91

Rows.0.inner.donm.detail.syn=C

Rows.0.inner.donm.detail.met-type=0

Rows.0.inner.donm.detail.neses.lldEDIT.0.ium=830

Rows.0.inner.donm.detail.neses.lldEDIT.0.m=1

Rows.0.inner.donm.detail.neses.lldEDIT.0.ass.ape=ipv4

Rows.0.inner.donm.detail.neses.lldEDIT.0.ass.ipvs=94

Rows.0.inner.donm.detail.pess=0008

Rows.0.inner.donm.detail.por]d=0

Rows.0.inner.donm.detail.pon=BCtive

Rows.0.inner.donm.detail.sysme=BC1

Rows.0.inner.donm.reme=Bu1

Rows.0.inner.donm.hean=0

Rows.0.inner.donm.porl=Et1

Tey.epath=Cgetail

Tey.sustr=MX

Tey.coime=1567621527653

Tey.msp=1567621527653

Tey.come=1567621527660

Tey.nor=BC5

Tey.cid=14789654


查看完整回答
反对 回复 2023-08-09
?
墨色风雨

TA贡献1853条经验 获得超6个赞

只需将每个级别的键附加到更高级别的键中即可创建键的命名空间。换句话说,你的扁平 JSON 的键将是:


{

 "L1key::L2key": "L2val",

 "L1key": "L1val",

 "L1key::L2key::L3key": "L3val"

}

这样你就可以保证唯一性,而且你也可以从中创建原始的 json。最后确保级别分隔符(此处::)不会出现在您的密钥中。


查看完整回答
反对 回复 2023-08-09
  • 4 回答
  • 0 关注
  • 177 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信