Cara menghapus pasangan nilai kunci dari file JSON di java
Saya bertanya-tanya apakah ada yang bisa membantu saya atau memberi petunjuk kepada saya tentang cara mengedit file JSON dummy terlampir di Java.
Seperti yang Anda lihat, saya memiliki objek kepala yang berisi banyak nilai dan anak yang mengikuti pola yang sama.
Saya ingin tahu apakah ada cara untuk menghapus semua kunci yang nilainya -1.

Berikut adalah apa yang saya coba berdasarkan banyak situs web yang menggunakan 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());
//
Kode di atas akan menampilkan struktur file, namun masalah saya adalah mencapai nilai -1 di dalam anak-anak dan menghapusnya.
Menggunakan metode .getClass dan .simpleName Saya tahu bahwa ini adalah arrayList tetapi saya bingung bagaimana cara mencarinya.
Bantuan apa pun akan sangat dihargai!
Jawaban
Di Jackson
Anda dapat membaca seluruh JSON
payload sebagai JsonNode
dan mengulangi semua properti, periksa kondisi yang diberikan. Jika kondisi terpenuhi, Anda dapat menghapus bidang tertentu. Untuk melakukan itu, Anda perlu menerapkan metode rekursif . Lihat contoh di bawah ini:
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);
}
}
}
Untuk JSON
muatan di bawah ini :
{
"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
}
]
}
]
}
cetakan kode di atas:
{
"name" : "Head",
"children" : [ {
"name" : "project1",
"children" : [ {
"name" : "project1",
"missed" : 10,
"covered" : 11
} ]
}, {
"name" : "project1",
"covered" : 12,
"children" : [ {
"name" : "project1",
"missed" : 10
} ]
} ]
}
Lihat juga:
- Meratakan string JSON bertingkat 3 tingkat di java
Ada dua teknik utama untuk mengurai dan menghasilkan data JSON (serta banyak format lain seperti XML dll): pemetaan objek dan pemrosesan berorientasi acara / token / aliran. Cara kedua adalah cara terbaik untuk banyak kasus, termasuk pemfilteran. Atribut:
- file / data tidak perlu dimuat seluruhnya ke dalam memori, Anda dapat memproses megs / gigs tanpa masalah
- ini bekerja lebih cepat, terutama untuk file besar
- mudah untuk menerapkan jenis / aturan transformasi kustom apa pun dengan pola ini
Baik Gson dan Jackson mendukung pemrosesan berorientasi aliran. Untuk menggambarkan idenya di sini hanyalah sebuah contoh menggunakan parser / generator kecilhttps://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
}
}
}