当前位置: 首页 > 知识库问答 >
问题:

用javax.json.jsonObject“深度替换”

赵晟睿
2023-03-14
{
   "Attr1":number1,
   "Attr2":number2,
   "Attr3":number3,
   "Attr4":[
      "string1"
   ],
   "Attr5":[
      {
         "Attr6":[
            {
               "Attr7":"string2",
               "Attr8":"string3",
               "$Attr9":number4
            },
            {
               "Attr7":"string4",
               "Attr8":"string5",
               "Attr9":number5
            }
         ],
         "Attr10":number6,
         "Attr14":{
            "Attr10":"string6",
            "Attr11":"string7",
            "Attr12":"string8"
         },
         "Attr13":[
            "string9",
            "string10"
         ],
         "Attr14":"string11"
      }
   ]
}
"Attr6":["newString1","newString2"],
public static JsonObject replaceValue( final JsonObject jsonObject, final String jsonKey, final JsonValue jsonValue )
{
  JsonObjectBuilder builder = Json.createObjectBuilder();

  if(jsonObject == null)
  {
    return builder.build();
  }

  Iterator<Entry<String, JsonValue>> it = jsonObject.entrySet().iterator();

  while (it.hasNext())
  {
    @SuppressWarnings( "rawtypes" )
    JsonObject.Entry mapEntry = it.next();

    if (mapEntry.getKey() == jsonKey)
    {
      builder.add(jsonKey, jsonValue);
    }
    else if (ValueType.STRING.equals(((JsonValue) mapEntry.getValue()).getValueType()) || ValueType.NUMBER.equals(((JsonValue) mapEntry.getValue()).getValueType()) || ValueType.TRUE.equals(((JsonValue) mapEntry.getValue()).getValueType()) ||
        ValueType.FALSE.equals(((JsonValue) mapEntry.getValue()).getValueType()) || (JsonValue) mapEntry.getValue() == null || "schemas".equalsIgnoreCase((String) mapEntry.getKey()))
    {
      builder.add(mapEntry.getKey().toString(), (JsonValue) mapEntry.getValue());
    }
    else if (ValueType.OBJECT.equals(((JsonValue) mapEntry.getValue()).getValueType()))
    {
      JsonObject modifiedJsonobject = (JsonObject) mapEntry.getValue();
      if (modifiedJsonobject != null)
      {
        replaceValue(modifiedJsonobject, jsonKey, jsonValue);
      }
    }
    else if (ValueType.ARRAY.equals(((JsonValue) mapEntry.getValue()).getValueType()))
    {
      for (int i = 0; i < ((JsonValue) mapEntry.getValue()).asJsonArray().size(); i++)
      {
        replaceValue((JsonObject) ((JsonValue) mapEntry.getValue()).asJsonArray().get(i), jsonKey, jsonValue);
      }
    }
  }

  return builder.build();
}

共有1个答案

米子轩
2023-03-14

这是解决这个问题的另一种方法,它使用javax.json.stream.jsonParser提供的流解析器。这将从JSON源代码生成一个令牌流,其中包含javax.JSON.stream.jsonparser.event值,这些值描述令牌的类型(例如start_objectkey_name等)。

对我们来说最重要的是,解析器上有skipobject()skiparray()方法,它们允许我们删除源JSON中不需要的部分。

总体方法是构建一个新版本的JSON,逐个令牌,作为一个字符串,当我们到达JSON中的相关位置(或多个位置)时,替换替换部分。

最后,我们将新字符串转换回一个对象,这样我们就可以漂亮地打印它了。

这种方法中不使用递归。

java prettyprint-override">import java.io.IOException;
import javax.json.Json;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.json.JsonObject;
import javax.json.JsonWriterFactory;
import javax.json.stream.JsonGenerator;

public class StreamDemo {

    public static void doStream() throws IOException {
        JsonParser jsonParser = Json.createParser(new StringReader(JSONSTRING));

        StringBuilder sb = new StringBuilder();
        Event previous = null;

        String targetKeyName = "Attr6";
        String replacement = "[\"newString1\",\"newString2\"]";
        // This event reflects the end of the "replacement" string - namely "]".
        // We need this because this event may be different from the replaced event.
        Event replacementPreviousEvent = Event.END_ARRAY;

        // Used when we find the target key for replacement:
        boolean doReplacement = false;

        while (jsonParser.hasNext()) {
            Event event = jsonParser.next();
            if (doReplacement) {
                // Skip over the structure we want to replace:
                if (event.equals(Event.START_OBJECT)) {
                    jsonParser.skipObject();
                } else if (event.equals(Event.START_ARRAY)) {
                    jsonParser.skipArray();
                }
                // Write the replacement fragment here:
                sb.append(replacement);
                // Move to the next event in the stream:
                event = jsonParser.next();
                previous = replacementPreviousEvent;
                doReplacement = false;
            }

            if (Event.KEY_NAME.equals(event)
                    && jsonParser.getString().equals(targetKeyName)) {
                doReplacement = true;
            }

            switch (event) {
                case START_OBJECT:
                    if (Event.END_OBJECT.equals(previous)) {
                        sb.append(",");
                    }
                    sb.append("{");
                    break;
                case END_OBJECT:
                    sb.append("}");
                    break;
                case START_ARRAY:
                    sb.append("[");
                    break;
                case END_ARRAY:
                    sb.append("]");
                    break;
                case KEY_NAME:
                    sb = previousWasAValue(previous, sb);
                    sb = previousWasAnEnd(previous, sb);
                    sb.append("\"").append(jsonParser.getString()).append("\":");
                    break;
                case VALUE_STRING:
                    sb = previousWasAValue(previous, sb);
                    sb.append("\"").append(jsonParser.getString()).append("\"");
                    break;
                case VALUE_NUMBER:
                    sb = previousWasAValue(previous, sb);
                    if (jsonParser.isIntegralNumber()) {
                        sb.append(jsonParser.getLong());
                    } else {
                        sb.append(jsonParser.getBigDecimal().toPlainString());
                    }
                    break;
                case VALUE_TRUE:
                    sb = previousWasAValue(previous, sb);
                    sb.append("true");
                    break;
                case VALUE_FALSE:
                    sb = previousWasAValue(previous, sb);
                    sb.append("false");
                    break;
                case VALUE_NULL:
                    sb = previousWasAValue(previous, sb);
                    sb.append("null");
                    break;
                default:
                    break;
            }
            previous = event;
        }
        
        // At the end, pretty-print the new JSON:
        JsonObject modifiedObject = Json.createReader(new StringReader(sb.toString())).readObject();
        Map<String, Boolean> config = new HashMap<>();
        config.put(JsonGenerator.PRETTY_PRINTING, true);
        String jsonString;
        JsonWriterFactory writerFactory = Json.createWriterFactory(config);
        try ( Writer writer = new StringWriter()) {
            writerFactory.createWriter(writer).write(modifiedObject);
            jsonString = writer.toString();
        }
        System.out.println(jsonString);
    }

    private static StringBuilder previousWasAValue(Event previous, StringBuilder sb) {
        // The current value follows another value - so a separating comma is needed:
        if (Event.VALUE_STRING.equals(previous)
                || Event.VALUE_NUMBER.equals(previous)
                || Event.VALUE_TRUE.equals(previous)
                || Event.VALUE_FALSE.equals(previous)
                || Event.VALUE_NULL.equals(previous)) {
            sb.append(",");
        }
        return sb;
    }

    private static StringBuilder previousWasAnEnd(Event previous, StringBuilder sb) {
        // The current key follows the end of an object or an array, so a 
        // separating comma is needed:
        if (Event.END_OBJECT.equals(previous)
                || Event.END_ARRAY.equals(previous)) {
            sb.append(",");
        }
        return sb;
    }

    private static final String JSONSTRING
            = """
    {
       "Attr0": null,
       "Attr1": true,
       "Attr2": false,
       "Attr3": 3,
       "Attr4": [
               "string1"
       ],
       "Attr5": [{
               "Attr6": [{
                               "Attr7": "string2",
                               "Attr8": "string3",
                               "Attr9": 4
                       },
                       {
                               "Attr7": "string4",
                               "Attr8": "string5",
                               "Attr9": 5
                       }
               ],
               "Attr10": 6,
               "Attr14": {
                       "Attr10": "string6",
                       "Attr11": "string7",
                       "Attr12": "string8"
               },
               "Attr13": [
                       "string9",
                       123.45,
                       false
               ],
               "Attr15": "string11"
       }]
    }
    """;

}
 类似资料:
  • 替换javax中的值。json。JsonObject不能直接使用,因为javax。json。JsonObject实现了一个不可变的映射。为了做到这一点,您必须创建一个新的JsonObject,并将值从原来的JsonObject复制到新的JsonObject中,同时替换要替换的值。我找到了如何使用“简单”JsonObject实现这一点的示例,其中没有嵌套的JsonObject。我要寻找的是一个通用的

  • 卷积神经网络(CNN) 卷积神经网络(Convolutional Neural Network,CNN)是将二维离散卷积运算和人工神经网络相结合的一种深度神经网络。它的特点是可以自动提取特征。有关卷积神经网络的数学原理和训练过程请见我的另一篇文章《机器学习教程 十五-细解卷积神经网络》。 手写数字识别 为了试验,我们直接采用http://yann.lecun.com/exdb/mnist/中的手写

  • 有时候你想要替换一个任务. 举个例子, 如果你想要互换一个通过 java 插件定义的任务和一个自定义的不同类型的任务: 例子 14.19. 覆写一个任务 build.gradle task copy(type: Copy) task copy(overwrite: true) << { println('I am the new one.') } gradle -q copy 的输出 >

  • 我正在Ubuntu上编写一个简单的OpenGL程序,它使用顶点数组绘制两个正方形(一个在另一个前面)。由于某种原因,GL_DEPTH_TEST似乎不起作用。后面的对象显示在前面的对象的前面。深度缓冲区由启用 GL_DEPTH_TEST由 并且深度缓冲区在绘制之前被清除 完整的代码如下所示: 顶点着色器如下所示:#version 130 片段着色器如下所示:#version 130 为什么前面的物体

  • 主要内容 课程列表 专项课程学习 辅助课程 论文专区 课程列表 课程 机构 参考书 Notes等其他资料 卷积神经网络视觉识别 Stanford 暂无 链接 神经网络 Tweet 暂无 链接 深度学习用于自然语言处理 Stanford 暂无 链接 自然语言处理 Speech and Language Processing 链接 专项课程学习 下述的课程都是公认的最好的在线学习资料,侧重点不同,但推

  • 本章将介绍如何使用接口在网站上进行对接 在网站<head></head>或<body></body>区域引入小能 js <script id="xiaonengjs" src="//visitor.ntalker.com/visitor/js/xiaoneng.js?siteid=您的网站id"></script> 如果您需要更新用户信息,如身份信息,您可以添加以下代码xn('setCustom