4 回答

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);
? ? }
? }
}
上面的代碼打?。?/p>
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

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

TA貢獻1853條經驗 獲得超6個贊
只需將每個級別的鍵附加到更高級別的鍵中即可創建鍵的命名空間。換句話說,你的扁平 JSON 的鍵將是:
{
"L1key::L2key": "L2val",
"L1key": "L1val",
"L1key::L2key::L3key": "L3val"
}
這樣你就可以保證唯一性,而且你也可以從中創建原始的 json。最后確保級別分隔符(此處::)不會出現在您的密鑰中。
添加回答
舉報