Java의 JSON 파일에서 키 값 쌍을 제거하는 방법
누구든지 나를 도와 줄 수 있는지 또는 첨부 된 더미 JSON 파일을 Java로 편집하는 방법에 대해 힌트를 줄 수 있는지 궁금합니다.
보시다시피 동일한 패턴을 따르는 많은 값과 자식을 포함하는 헤드 개체가 있습니다.
값이 -1 인 모든 키를 제거하는 방법이 있는지 알고 싶었습니다.

다음은 다음을 사용하는 많은 웹 사이트를 기반으로 시도한 것입니다 jackson
.
try {
// create object mapper instance
ObjectMapper mapper = new ObjectMapper();
// convert JSON file to map
Map<?, ?> map = mapper.readValue(Paths.get("test.json").toFile(), Map.class);
// print map entries
for (Map.Entry<?, ?> entry : map.entrySet()) {
isInteger = main.isObjectInteger(entry.getValue());
// System.out.println("if value is all: " + entry.getKey() + "=" + entry.getValue());
//
위의 코드는 파일의 구조를 표시하지만 내 문제는 자식 내부의 -1 값에 도달하여 제거하는 것입니다.
.getClass 및 .simpleName 메서드를 사용하여 그것이 arrayList라는 것을 알고 있지만 검색 방법에 대해서는 혼란 스럽습니다.
어떤 도움이라도 대단히 감사하겠습니다!
답변
에서 Jackson
전체 JSON
페이로드를 읽고 JsonNode
주어진 조건을 모든 속성 검사에 대해 반복 할 수 있습니다 . 조건이 충족되면 주어진 필드를 제거 할 수 있습니다. 그렇게하려면 재귀 메서드 를 구현해야합니다 . 아래 예를 살펴보십시오.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
public class JsonRemoveSomeFieldsApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
JsonNode root = mapper.readTree(jsonFile);
JsonCleaner jsonCleaner = new JsonCleaner(root, (node) -> node.isNumber() && node.numberValue().intValue() == -1);
JsonNode result = jsonCleaner.removeAll();
// write to file
mapper.writeValue(System.out, result);
}
}
class JsonCleaner {
private final JsonNode root;
private final Predicate<JsonNode> toRemoveCondition;
JsonCleaner(JsonNode node, Predicate<JsonNode> toRemoveCondition) {
this.root = Objects.requireNonNull(node);
this.toRemoveCondition = Objects.requireNonNull(toRemoveCondition);
}
public JsonNode removeAll() {
process(root);
return root;
}
private void process(JsonNode node) {
if (node.isObject()) {
ObjectNode object = (ObjectNode) node;
Iterator<Map.Entry<String, JsonNode>> fields = object.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> field = fields.next();
JsonNode valueToCheck = field.getValue();
if (valueToCheck.isContainerNode()) {
process(valueToCheck);
} else if (toRemoveCondition.test(valueToCheck)) {
fields.remove();
}
}
} else if (node.isArray()) {
ArrayNode array = (ArrayNode) node;
array.elements().forEachRemaining(this::process);
}
}
}
아래 JSON
페이로드의 경우 :
{
"name": "Head",
"missed": -1,
"covered": -1,
"children": [
{
"name": "project1",
"missed": -1,
"covered": -1,
"children": [
{
"name": "project1",
"missed": 10,
"covered": 11
}
]
},
{
"name": "project1",
"missed": -1,
"covered": 12,
"children": [
{
"name": "project1",
"missed": 10,
"covered": -1
}
]
}
]
}
위의 코드는 다음을 인쇄합니다.
{
"name" : "Head",
"children" : [ {
"name" : "project1",
"children" : [ {
"name" : "project1",
"missed" : 10,
"covered" : 11
} ]
}, {
"name" : "project1",
"covered" : 12,
"children" : [ {
"name" : "project1",
"missed" : 10
} ]
} ]
}
또한보십시오:
- 자바에서 3 단계 중첩 JSON 문자열 병합
JSON 데이터를 구문 분석하고 생성하는 두 가지 주요 기술 (XML과 같은 다른 형식 포함)이 있습니다. 객체 매핑과 이벤트 / 토큰 / 스트림 지향 처리입니다. 두 번째 방법은 필터링을 포함하여 많은 경우에 가장 좋은 방법입니다. 소품:
- 파일 / 데이터를 완전히 메모리에로드 할 필요가 없습니다. 문제없이 megs / gigs를 처리 할 수 있습니다.
- 특히 대용량 파일의 경우 훨씬 더 빠르게 작동합니다.
- 이 패턴으로 사용자 정의 유형 / 변환 규칙을 쉽게 구현할 수 있습니다.
Gson과 Jackson은 모두 스트림 지향 처리를 지원합니다. 여기에 아이디어를 설명하기 위해 작은 파서 / 생성기를 사용하는 예가 있습니다.https://github.com/anatolygudkov/green-jelly
import org.green.jelly.AppendableWriter;
import org.green.jelly.JsonBufferedWriter;
import org.green.jelly.JsonEventPump;
import org.green.jelly.JsonNumber;
import org.green.jelly.JsonParser;
import java.io.StringWriter;
public class UpdateMyJson {
private static final String jsonToUpdate = "{\n" +
"\"name\": \"Head\",\n" +
"\"missed\": -1,\n" +
"\"children\": [\n" +
" {\n" +
" \"name\": \"project1\",\n" +
" \"fixes\": 0,\n" +
" \"commits\": -1,\n" +
" },\n" +
" {\n" +
" \"name\": \"project2\",\n" +
" \"fixes\": 20,\n" +
" \"commits\": 5,\n" +
" }\n" +
"]\n" +
"}";
public static void main(String[] args) {
final StringWriter result = new StringWriter(); // you can use FileWriter
final JsonParser parser = new JsonParser();
parser.setListener(new MyJsonUpdater(new AppendableWriter<>(result)));
parser.parseAndEoj(jsonToUpdate); // if you read a file with a buffer,
// to don't load the whole file into memory,
// call parse() several times (part by part) in a loop until EOF
// and then call .eoj()
System.out.println(result);
}
static class MyJsonUpdater extends JsonEventPump {
MyJsonUpdater(final JsonBufferedWriter output) {
super(output);
}
@Override
public boolean onNumberValue(final JsonNumber number) {
if (number.mantissa() == -1 && number.exp() == 0) {
return true; // return immediately
}
return super.onNumberValue(number); // otherwise pump the value to the result JSON
}
}
}