要求是为将输入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等类型的值时,事情变得越来越复杂。而且,我无法理解如何维护嵌套键的唯一性。
public static Map<String,Object> flattenJson(JsonNode input){
Map<String,Object> finalMap = new HashMap<>();
ObjectMapper datamapper = new ObjectMapper();
Map<String,Object> topLevelJsonMap = datamapper.convertValue(input,Map.class);
Set<String> topLevelKeys = topLevelJsonMap.keySet();
for(String topLevelKey : topLevelKeys){
System.out.println("Key :::: "+topLevelKey);
Object topLevelData = topLevelJsonMap.get(topLevelKey);
System.out.println("value :::: "+topLevelData.toString());
if(topLevelData instanceof ArrayNode){
ArrayNode arrayOfData = (ArrayNode) topLevelData;
for(JsonNode dataNode : arrayOfData){
flattenJson(input);
}
} else if(topLevelData instanceof JsonNode){
Map<String,Object> innerLevelJsonMap = datamapper.convertValue(topLevelData,Map.class);
Set<String> innerLevelKeys = innerLevelJsonMap.keySet();
for(String innerLevelKey : innerLevelKeys){
System.out.println("inner key :::: "+innerLevelKey);
flattenJson((JsonNode) innerLevelJsonMap.get(innerLevelKey));
}
}else {
finalMap.put(topLevelKey,topLevelData);
}
}
return finalMap;
}
任何帮助是极大的赞赏。
为了避免与键名冲突,可以使用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
我有一门java课 在上面的场景中,示例具有子示例,这又是示例列表。此嵌套可以是 n 级。我想实现的是有一个示例列表,即扁平化上面的对象并将所有示例收集到最终列表中(收集所有n级示例)。一个明显的方法是递归。在Java中有什么方法可以更有效地实现它。我尝试了一些java 8概念,但它们不符合要求。
问题内容: 我正在处理一个复杂的嵌套字典和列表数据结构。我需要将数据展平并将所有嵌套项都置于0级。有关更多说明,请参见以下示例: 我需要将其展平为: 我从这篇文章的第一个答案中获得了参考,但是只有在我嵌套了字典的情况下它才可以工作,如果列表嵌套在字典中并且更多的词典嵌套在这些列表中,则它不能工作。 我对代码做了一些修改以适合我的用例,但是此代码不起作用 当我在此处粘贴代码时,缩进变得混乱。但我真的
问题内容: 我想拉平一个嵌套的JSON对象,如以为了消化它Solr中。 我有11 TB的json文件,这些文件既嵌套又包含字段名称中的点,这意味着elasticsearch(点)或solr(嵌套时不带符号)都不能按原样消化它。 其他解决方案是用下划线替换字段名称中的点并将其推送到elasticsearch,但是我对solr有更好的经验,因此我更喜欢扁平化解决方案(除非solr可以按原样消化那些嵌套
问题内容: 我正在尝试将JSON转换为CSV文件,可用于进一步分析。我的结构存在的问题是,当我转换JSON文件时,我有很多嵌套的字典/列表。 我尝试使用pandas ,但它只会使第一级扁平化。 任何想法如何讨好整个JSON文件,以便我可以为单个(在本例中为虚拟机)条目创建到CSV文件的单行输入?我已经尝试过这里发布的几种解决方案,但是我的结果始终只是将第一级展平。 这是示例JSON(在这种情况下,
问题内容: 我正在尝试将json文件加载到熊猫数据框。我发现有一些嵌套的json。以下是示例json: 我使用以下代码将json加载到数据帧中: 以下是df.head()的输出 但是我发现了两个嵌套的列,例如位置和标签。 我尝试使用以下代码对其进行展平: 它显示了如下错误: 您能建议我如何展平位置和标签(那些具有嵌套数据的位置和标签)。 谢谢,Zep 问题答案: 如果您正在寻找一种更通用的方法来从
问题内容: 也许有人可以帮助我。我试图将以下ist放到pandas数据框中: 结果应如下所示: 但是我尝试做的所有事情都无法获得预期的结果。我用了这样的东西: 但是然后我松开了_source字段之外的类型。我也尝试与 但是我不知道如何使用字段_source并将其附加到原始数据帧。 有人知道如何做到这一点并达到预期的结果吗? 问题答案: 用途: