Как удалить весь ключ и его значение определенного имени ключа из строки JSON (с детьми) в Java
Я хочу удалить весь ключ "id" и его значение из моей строки json. Проблема в том, что "id" встречается на многих уровнях в моей строке json. Я использую JSONObject. С JSONObject мы можем удалить "id" только на верхнем уровне, но мне нужно удалить "id" на каждом уровне. пожалуйста, помогите мне
Ex строки json -
"{
"success": {
"body": {
"id": 5827,
"siteName": "RPX",
"instances": [
{
"instanceId": "i-3a63035e",
"name": "prdae-mst21a (iserver)",
"state": "running",
"publicDnsName": "ec2-54-209-175-118.compute-1.amazonaws.com",
"tags": [
{
"id": 9783,
"key": "ktier",
"value": "da"
},
{
"id": 9782,
"key": "Name",
"value": "prdae-mst21a (iserver)"
},
{
"id": 9781,
"key": "kreg",
"value": "e"
}
],
"sshAccessInfo": {
"id": 9788,
"keyPair": {
"id": 6050,
"keyName": "Kens key",
"status": "UPLOADED",
"defaultUser": "root",
"passPhrase": "imaginea#@!"
},
"userName": "imaginea"
},
"account": {
"id": 5857,
"accountId": "348713271046",
"type": "AWS",
"ownerAlias": "348713271046",
"regionName": "us-east-1"
},
"availabilityZone": "us-east-1a",
"publicIpAddress": "54.209.175.118",
"instanceType": "m2.2xlarge"
},
{
"instanceId": "i-65ad2346",
"name": "prpoe-pap22e cp",
"state": "running",
"publicDnsName": "ec2-54-86-2-65.compute-1.amazonaws.com",
"tags": [
{
"id": 9755,
"key": "kzone",
"value": "e"
},
{
"id": 9754,
"key": "kreg",
"value": "e"
}
],
"sshAccessInfo": {
"id": 9756,
"keyPair": {
"id": 5895,
"keyName": "rpxprod-rightscale",
"status": "UPLOADED",
"defaultUser": "ubuntu",
"passPhrase": "imaginea#@!"
},
"userName": "imaginea"
},
"account": {
"id": 5857,
"accountId": "348713271046",
"type": "AWS",
"ownerAlias": "348713271046",
"regionName": "us-east-1"
},
"availabilityZone": "us-east-1e",
"publicIpAddress": "54.86.2.65",
"instanceType": "m1.large"
} ],
"filters": [
{
"id": 5828,
"accountInfo": {
"id": 5829,
"type": "AWS",
"regionName": "us-east-1"
}
}
],
"loadBalancers": [
{
"id": 5855,
"name": "st-pgpool-cp",
"vpcId": "vpc-865c68ee",
"instanceIds": [
"i-b81511eb"
],
"availabilityZones": [
"us-east-1e"
]
},
{
"id": 5850,
"name": "pr-pgpool-cp",
"vpcId": "vpc-865c68ee",
"instanceIds": [
"i-ed262988"
],
"availabilityZones": [
"us-east-1d"
]
}
{
"id": 5844,
"name": "qa2-api",
"vpcId": "vpc-865c68ee",
"instanceIds": [
"i-63687842"
],
"availabilityZones": [
"us-east-1a"
]
},
{
"id": 5830,
"name": "prod-portal-https-v31",
"vpcId": "vpc-865c68ee",
"instanceIds": [
"i-97509bfa",
"i-660f0408"
],
"availabilityZones": [
"us-east-1e",
"us-east-1d"
]
}
]
}
}
}"
я хочу удалить id
от body
, instances
, sshAccessInfo
, filters
, loadBalancer
и т.д. Пожалуйста, предоставьте достойный способ для этого.
5 ответов
Не очень хорошо, но если это может быть действительно динамично, то вы можете использовать регулярное выражение и replaceAll()
чтобы удалить требуемые значения ключа из строки JSON, прежде чем анализировать что-либо:
json = json.replaceAll("\"" + prop + "\"[ ]*:[^,}\\]]*[,]?", "")
В твоем случае String prop = "id"
,
Мой ответ такой же, как у @frank.zheng, за исключением того, что я добавил оператор if, который проверяет, являются ли дочерние элементы массива объектами, прежде чем он попытается вернуться обратно в функцию.
public static void removeJSONField(JSONObject obj) throws JSONException{
obj.remove("id");
Iterator<String> it = obj.keys();
while(it.hasNext()){
String key = it.next();
Object childObj = obj.get(key);
if(childObj instanceof JSONArray){
JSONArray arrayChildObjs =((JSONArray)childObj);
int size = arrayChildObjs.length();
for(int i=0;i<size;i++){
if (arrayChildObjs.get(i) instanceof JSONObject){
removeJSONField(arrayChildObjs.getJSONObject(i));
}
}
}
if(childObj instanceof JSONObject){
removeJSONField(((JSONObject) childObj));
}
}
}
Пожалуйста, проверьте следующий фрагмент кода. Это должно встретить тебя хорошо
/**
* @param args
*/
public static void main(String[] args) {
String jsonStr ="{'id':'2839','body':{'id':'22',objs:[{id:1},{id:2}]}}";
try {
JSONObject obj = new JSONObject(jsonStr);
removeJSONField(obj);
System.out.println(obj);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void removeJSONField(JSONObject obj) throws JSONException{
obj.remove("id");
Iterator<String> it = obj.keys();
while(it.hasNext()){
String key = it.next();
Object childObj = obj.get(key);
if(childObj instanceof JSONArray){
JSONArray arrayChildObjs =((JSONArray)childObj);
int size = arrayChildObjs.length();
for(int i=0;i<size;i++){
removeJSONField(arrayChildObjs.getJSONObject(i));
}
}
if(childObj instanceof JSONObject){
removeJSONField(((JSONObject) childObj));
}
}
}
Это мое решение удалить все ключи, соответствующие заданному префиксу:
void removeKeysWithPrefix(JSONObject obj, String prefix) {
Iterator<String> itr;
String theKey="*something*from*nothing*";
Object theObj;
JSONArray theItems;
JSONObject theItem;
int size;
itr = obj.keys();
while (itr.hasNext()) {
theKey = itr.next();
theObj = obj.get(theKey);
if (theKey.startsWith(prefix)) {
itr.remove();
} else
if (theObj instanceof JSONArray) {
theItems = ((JSONArray)theObj);
size = theItems.length();
for (int i=0;i<size;i++) {
if (theItems.get(i) instanceof JSONObject) {
theItem = theItems.getJSONObject(i);
removeKeysWithPrefix(theItem, prefix);
}
}
} else
if (theObj instanceof JSONObject) {
removeKeysWithPrefix( ((JSONObject)theObj), prefix);
}
}
}
Шаг 1 - разобрать вашу строку JSON в набор объектов. Существует несколько библиотек JSON для Java, и их не очень сложно использовать. Используя, например, javax.json, вы сделаете следующее:
- Создать
StringReader
или жеByteArrayInputStream
который ссылается на вашу строку JSON. - Вызов
Json.createReader()
чтобы получить читателя JSON. - Вызов
JSONReader.read()
или жеJSONReader.readObject()
проанализировать строку в набор объектов JSON. - Измените ваши объекты JSON по мере необходимости.
- Создайте средство записи JSON и преобразуйте объекты JSON обратно в строку, если вам это нужно.
Другие библиотеки JSON будут следовать аналогичному процессу, хотя их конкретные имена классов могут отличаться.