在JsonElement中递归键搜索不会返回值。

huangapple go评论77阅读模式
英文:

Recursive key search in JsonElement does not return value

问题

我面临一个相对简单的递归函数的问题,我从<https://stackoverflow.com/questions/31157781/find-value-for-a-key-from-a-dynamic-json-using-java>修改了这个函数。该函数用于在嵌套的 JsonElement(arg2)中搜索键(arg1),如果输入中匹配了键,则返回其对应的值。原始方法是一个无返回值的方法,它会将值存储在静态列表中,但我需要将方法更改为返回一个字符串。

我面临的问题是,虽然该算法在 JSON 结构中递归搜索,当找到正确的键并返回其值时,但由于反复调用方法本身,它实际上并未退出方法。这在这个链接中有解释:<https://stackoverflow.com/questions/15727019/java-return-not-exiting-method-loops>。因此,该方法总是返回一个“没有值”的字符串。

我尝试了不同的策略来解决这个问题,但都没有成功。

我可以请您帮助解决这个问题吗?

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class Utils {
    
    public Utils() {}
    
    public String searchJson(String key, JsonElement jsonElement) {
        
        String value = "No value";
        
        // 如果输入是数组,则遍历每个元素
        if (jsonElement.isJsonArray()) {
            for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
                searchJson(key, jsonElement1);
            }
        }
        
        else {
            
            // 如果输入是对象,则遍历键
            if (jsonElement.isJsonObject()) {
                Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
                        .getAsJsonObject().entrySet();
                for (Map.Entry<String, JsonElement> entry : entrySet) {
                    
                    // 如果键对应
                    String key1 = entry.getKey();
                    if (key1.equals(key)) {
                        value = entry.getValue().toString();
                        return value;
                    }
                    
                    // 以 entry 作为输入,递归调用 searchJson 方法
                    searchJson(key, entry.getValue());
                }
            }
            
            // 如果输入是元素,检查它是否与键相对应
            else {
                if (jsonElement.toString().equals(key)) {
                    value = jsonElement.toString();
                    return value;
                }
            }
        }
        return value;
    }
    
    
    public static void main(String[] args) {
        
        Utils utils = new Utils();
        
        // 创建 JSON 响应
        String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}\r\n";
        JsonParser parser = new JsonParser();
        JsonObject json = parser.parse(response.toString()).getAsJsonObject();
        
        System.out.println(json.toString());
        System.out.println();
        
        // 访问卡片响应
        JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
                .get(0).getAsJsonObject()
                .get("cards").getAsJsonArray();
        
        // 遍历各个响应
        Iterator<JsonElement> cardIter = cardResponse.iterator();
        
        while (cardIter.hasNext()) {
            
            // 选择下一张卡片
            JsonObject card = cardIter.next().getAsJsonObject();
            System.out.println(card);
            
            String key = "Status";
            
            // TODO: 用地图中的变量替换
            // 如果所选的卡片 ID 对应迭代器中的 ID,
            // 则搜索与所选端点关联的值
            String cardId = card.get("card").getAsString();
            if (cardId.equals("MTE14019798")) {
                String value = utils.searchJson(key, card);
                System.out.print(value);
            }
        }
    }
}
英文:

I am facing a problem with a relatively simple recursive function, I adapted from <https://stackoverflow.com/questions/31157781/find-value-for-a-key-from-a-dynamic-json-using-java>. The function consists of searching for a key (arg1) in a nested JsonElement (arg2) and if the key is matched in the input, returning its corresponding value. The original method consisted of a void method that would have stored the value(s) in a static list but I need to change the method to return a String.

The problem I am facing is that, although the algorithm manages to search recursively within the structure of the JSON when it finds the right key and returns its value, it does not actually exit the method due to the recursive calling of the method itself. This is explained in this link: <https://stackoverflow.com/questions/15727019/java-return-not-exiting-method-loops>. Hence, the method always returns a "No value" string.

I have tried different tactics to solve this but unsuccessfully.

Can I please ask your help to solve this?

import java.util.Map;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class Utils {
public Utils() {}
public String searchJson(String key, JsonElement jsonElement) {
String value = &quot;No value&quot;;
// If input is an array, iterate through each element
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
searchJson(key, jsonElement1);
}
}
else {
// If input is object, iterate through the keys
if (jsonElement.isJsonObject()) {
Set&lt;Map.Entry&lt;String, JsonElement&gt;&gt; entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry&lt;String, JsonElement&gt; entry : entrySet) {
// If key corresponds to the 
String key1 = entry.getKey();
if (key1.equals(key)) {
value = entry.getValue().toString();
return value;
}
// Use the entry as input, recursively
searchJson(key, entry.getValue());
}
}
// If input is element, check whether it corresponds to the key
else {
if (jsonElement.toString().equals(key)) {
value = jsonElement.toString();
return value;
}
}
}
return value;
}
public static void main(String[] args) {
Utils utils = new Utils();
// Create JSON response
String response = &quot;{\&quot;jsonData\&quot;:[{\&quot;cards\&quot;:[{\&quot;card\&quot;:\&quot;MTE14019797\&quot;,\&quot;Explanation\&quot;:{\&quot;Message\&quot;:\&quot;No explaination key identified\&quot;,\&quot;Status\&quot;:\&quot;Failed\&quot;},\&quot;Prediction\&quot;:{\&quot;Confidence_intervals\&quot;:[{\&quot;confidence\&quot;:\&quot;0.614\&quot;,\&quot;distance\&quot;:\&quot;0.3\&quot;,\&quot;range_lower\&quot;:\&quot;1.117\&quot;,\&quot;range_upper\&quot;:\&quot;1.717\&quot;}],\&quot;Message\&quot;:\&quot;\&quot;,\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;point_estimate\&quot;:\&quot;1.417\&quot;}},{\&quot;card\&quot;:\&quot;MTE14019798\&quot;,\&quot;Explanation\&quot;:{\&quot;Message\&quot;:\&quot;No explaination key identified\&quot;,\&quot;Status\&quot;:\&quot;Failed\&quot;},\&quot;Prediction\&quot;:{\&quot;Confidence_intervals\&quot;:[{\&quot;confidence\&quot;:\&quot;0.584\&quot;,\&quot;distance\&quot;:\&quot;0.3\&quot;,\&quot;range_lower\&quot;:\&quot;1.852\&quot;,\&quot;range_upper\&quot;:\&quot;2.452\&quot;}],\&quot;Message\&quot;:\&quot;\&quot;,\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;point_estimate\&quot;:\&quot;2.152\&quot;}}],\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;modelTarget\&quot;:\&quot;MTEter\&quot;,\&quot;modelType\&quot;:\&quot;conformalRegression\&quot;,\&quot;modelUpdated\&quot;:\&quot;2020-09-01\&quot;,\&quot;principalResults\&quot;:[\&quot;point_estimate\&quot;,\&quot;confidence\&quot;,\&quot;distance\&quot;,\&quot;modelUpdated\&quot;]}]}\r\n&quot;;
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(response.toString()).getAsJsonObject();
System.out.println(json.toString());
System.out.println();
// Access card response
JsonArray cardResponse = json.get(&quot;jsonData&quot;).getAsJsonArray()
.get(0).getAsJsonObject()
.get(&quot;cards&quot;).getAsJsonArray();
// Iterate through individual responses
Iterator&lt;JsonElement&gt; cardIter = cardResponse.iterator();
while (cardIter.hasNext()) {
// Select next card
JsonObject card = cardIter.next().getAsJsonObject();
System.out.println(card);
String key = &quot;Status&quot;;
// TODO: Replace with variable from map
// If selected card Id corresponds to that in the iterator, 
// then search for the value associated to the selected end-point 
String cardId = card.get(&quot;card&quot;).getAsString();
if (cardId.equals(&quot;MTE14019798&quot;)) {
String value = utils.searchJson(key, card);
System.out.print(value);
}
}
}
}```
</details>
# 答案1
**得分**: 0
```java
class Utils {
public Utils() {
}
public String searchJson(String key, JsonElement jsonElement) {
String value = null;
// If input is an array, iterate through each element
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
value = searchJson(key, jsonElement1);
if (value != null) {
return value;
}
}
} else {
// If input is object, iterate through the keys
if (jsonElement.isJsonObject()) {
Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
// If key corresponds to the
String key1 = entry.getKey();
if (key1.equals(key)) {
value = entry.getValue().toString();
return value;
}
// Use the entry as input, recursively
value = searchJson(key, entry.getValue());
if (value != null) {
return value;
}
}
}
// If input is element, check whether it corresponds to the key
else {
if (jsonElement.toString().equals(key)) {
value = jsonElement.toString();
return value;
}
}
}
return value;
}
}
class Main {
public static void main(String[] args) {
Utils utils = new Utils();
// Create JSON response
String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}";
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(response).getAsJsonObject();
System.out.println(json.toString());
System.out.println();
// Access card response
JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
.get(0).getAsJsonObject()
.get("cards").getAsJsonArray();
// Iterate through individual responses
Iterator<JsonElement> cardIter = cardResponse.iterator();
while (cardIter.hasNext()) {
// Select next card
JsonObject card = cardIter.next().getAsJsonObject();
System.out.println(card);
String key = "Status";
// TODO: Replace with variable from map
// If selected card Id corresponds to that in the iterator,
// then search for the value associated with the selected end-point
String cardId = card.get("card").getAsString();
if (cardId.equals("MTE14019798")) {
String value = utils.searchJson(key, card);
System.out.print(value);
}
}
}
}

Note: The provided code contains HTML escape characters (e.g., &quot;) that are not visible here. Please make sure to replace them with the actual characters when using the code.

英文:

You are not returning the value in recursive calls hence it is getting lost , you can save your return value in a variable and check for null, if it's not null you have found the value and you can break from any loops and return from recursive function.

I have modified some parts, Go through it. Also, Add null checks wherever required.

class Utils {
public Utils() {
}
public String searchJson(String key, JsonElement jsonElement) {
String value = null;
// If input is an array, iterate through each element
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
value = searchJson(key, jsonElement1);
if (value != null) {
return value;
}
}
} else {
// If input is object, iterate through the keys
if (jsonElement.isJsonObject()) {
Set&lt;Map.Entry&lt;String, JsonElement&gt;&gt; entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry&lt;String, JsonElement&gt; entry : entrySet) {
// If key corresponds to the
String key1 = entry.getKey();
if (key1.equals(key)) {
value = entry.getValue().toString();
return value;
}
// Use the entry as input, recursively
value = searchJson(key, entry.getValue());
if (value != null) {
return value;
}
}
}
// If input is element, check whether it corresponds to the key
else {
if (jsonElement.toString().equals(key)) {
value = jsonElement.toString();
return value;
}
}
}
return value;
}
}
class Main {
public static void main(String[] args) {
Utils utils = new Utils();
// Create JSON response
String response = &quot;{\&quot;jsonData\&quot;:[{\&quot;cards\&quot;:[{\&quot;card\&quot;:\&quot;MTE14019797\&quot;,\&quot;Explanation\&quot;:{\&quot;Message\&quot;:\&quot;No explaination key identified\&quot;,\&quot;Status\&quot;:\&quot;Failed\&quot;},\&quot;Prediction\&quot;:{\&quot;Confidence_intervals\&quot;:[{\&quot;confidence\&quot;:\&quot;0.614\&quot;,\&quot;distance\&quot;:\&quot;0.3\&quot;,\&quot;range_lower\&quot;:\&quot;1.117\&quot;,\&quot;range_upper\&quot;:\&quot;1.717\&quot;}],\&quot;Message\&quot;:\&quot;\&quot;,\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;point_estimate\&quot;:\&quot;1.417\&quot;}},{\&quot;card\&quot;:\&quot;MTE14019798\&quot;,\&quot;Explanation\&quot;:{\&quot;Message\&quot;:\&quot;No explaination key identified\&quot;,\&quot;Status\&quot;:\&quot;Failed\&quot;},\&quot;Prediction\&quot;:{\&quot;Confidence_intervals\&quot;:[{\&quot;confidence\&quot;:\&quot;0.584\&quot;,\&quot;distance\&quot;:\&quot;0.3\&quot;,\&quot;range_lower\&quot;:\&quot;1.852\&quot;,\&quot;range_upper\&quot;:\&quot;2.452\&quot;}],\&quot;Message\&quot;:\&quot;\&quot;,\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;point_estimate\&quot;:\&quot;2.152\&quot;}}],\&quot;Status\&quot;:\&quot;Success\&quot;,\&quot;modelTarget\&quot;:\&quot;MTEter\&quot;,\&quot;modelType\&quot;:\&quot;conformalRegression\&quot;,\&quot;modelUpdated\&quot;:\&quot;2020-09-01\&quot;,\&quot;principalResults\&quot;:[\&quot;point_estimate\&quot;,\&quot;confidence\&quot;,\&quot;distance\&quot;,\&quot;modelUpdated\&quot;]}]}\r\n&quot;;
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(response.toString()).getAsJsonObject();
System.out.println(json.toString());
System.out.println();
// Access card response
JsonArray cardResponse = json.get(&quot;jsonData&quot;).getAsJsonArray()
.get(0).getAsJsonObject()
.get(&quot;cards&quot;).getAsJsonArray();
// Iterate through individual responses
Iterator&lt;JsonElement&gt; cardIter = cardResponse.iterator();
while (cardIter.hasNext()) {
// Select next card
JsonObject card = cardIter.next().getAsJsonObject();
System.out.println(card);
String key = &quot;Status&quot;;
// TODO: Replace with variable from map
// If selected card Id corresponds to that in the iterator,
// then search for the value associated to the selected end-point
String cardId = card.get(&quot;card&quot;).getAsString();
if (cardId.equals(&quot;MTE14019798&quot;)) {
String value = utils.searchJson(key, card);
System.out.print(value);
}
}
}
}

huangapple
  • 本文由 发表于 2020年9月6日 19:10:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63763474.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定