Inshort:我试图找到一些api,通过将第一个参数作为jsonString,第二个参数作为JSONPath,第三个参数将是该参数的新值来改变值。但是,我发现的只是这个。。https://code.google.com/p/json-path/
这个api允许我在JSON字符串中查找任何值。但是,我没有找到简单的方法来更新任何键的值。例如,这里有一本书。json。
{
"store":{
"book":[
{
"category":"reference",
"author":"Nigel Rees",
"title":"Sayings of the Century",
"price":8.95
},
{
"category":"fiction",
"author":"Evelyn Waugh",
"title":"Sword of Honour",
"price":12.99,
"isbn":"0-553-21311-3"
}
],
"bicycle":{
"color":"red",
"price":19.95
}
}
}
我可以通过这样做访问自行车的颜色。
String bicycleColor = JsonPath.read(json, "$.store.bicycle.color");
但我正在JsonPath或其他api中寻找这样的方法
JsonPath.changeNodeValue(json, "$.store.bicycle.color", "green");
String bicycleColor = JsonPath.read(json, "$.store.bicycle.color");
System.out.println(bicycleColor); // This should print "green" now.
我排除了这些选项,
原因:对于不同类型的服务,我有大约500个不同的请求,这些请求返回不同的json结构。所以,我不想总是手动创建新的JSON字符串。因为,ID在json结构中是动态的。
任何想法或方向都值得赞赏。
用以下答案更新此问题。
>
复制这个小片段并根据需要进行修改。
private static void updateJsonValue() {
JSONParser parser = new JSONParser();
JSONObject jsonObject = new JSONObject();
FileReader reader = null;
try {
File jsonFile = new File("path to book.json");
reader = new FileReader(jsonFile);
jsonObject = (JSONObject) parser.parse(reader);
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
Map<String, Object> userData = null;
try {
userData = new ObjectMapper().readValue(jsonObject.toJSONString(), Map.class);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MutableJson json = new MutableJson(userData);
System.out.println("Before:\t" + json.map());
json.update("$.store.book[0].author", "jigish");
json.update("$.store.book[1].category", "action");
System.out.println("After:\t" + json.map().toString());
}
使用这些库。
只是回答人们登陆此页面的未来参考。
您可以考虑使用jsonpatch的Java实现。RFC可以在这里找到
JSON补丁是一种描述JSON文档更改的格式。它可以用来避免在只有一部分发生更改时发送整个文档。当与HTTP补丁方法结合使用时,它允许以符合标准的方式对HTTP API进行部分更新。
您可以指定需要执行的操作(替换、添加......)、必须执行的json路径以及应该使用的值。
同样,以RFC为例:
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
对于Java实现,我自己没有使用过,但您可以尝试https://github.com/fge/json-patch
假设已解析的JSON可以在内存中表示为映射,则可以构建类似于JsonPath的API,如下所示:
void update(Map<String, Object> json, String path, Object newValue);
我已经快速完成了一个简单的特定路径(不支持条件和通配符)的脏实现的要点,这些路径可以遍历json树,例如$.store.name,$.store.books[0]. isbn。在这里:MutableJson.java.它肯定需要改进,但可以给一个好的开始。
用法示例:
import java.util.*;
public class MutableJson {
public static void main(String[] args) {
MutableJson json = new MutableJson(
new HashMap<String, Object>() {{
put("store", new HashMap<String, Object>() {{
put("name", "Some Store");
put("books", Arrays.asList(
new HashMap<String, Object>() {{
put("isbn", "111");
}},
new HashMap<String, Object>() {{
put("isbn", "222");
}}
));
}});
}}
);
System.out.println("Before:\t" + json.map());
json.update("$.store.name", "Book Store");
json.update("$.store.books[0].isbn", "444");
json.update("$.store.books[1].isbn", "555");
System.out.println("After:\t" + json.map());
}
private final Map<String, Object> json;
public MutableJson(Map<String, Object> json) {
this.json = json;
}
public Map<String, Object> map() {
return json;
}
public void update(String path, Object newValue) {
updateJson(this.json, Path.parse(path), newValue);
}
private void updateJson(Map<String, Object> data, Iterator<Token> path, Object newValue) {
Token token = path.next();
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (!token.accept(entry.getKey(), entry.getValue())) {
continue;
}
if (path.hasNext()) {
Object value = token.value(entry.getValue());
if (value instanceof Map) {
updateJson((Map<String, Object>) value, path, newValue);
}
} else {
token.update(entry, newValue);
}
}
}
}
class Path {
public static Iterator<Token> parse(String path) {
if (path.isEmpty()) {
return Collections.<Token>emptyList().iterator();
}
if (path.startsWith("$.")) {
path = path.substring(2);
}
List<Token> tokens = new ArrayList<>();
for (String part : path.split("\\.")) {
if (part.matches("\\w+\\[\\d+\\]")) {
String fieldName = part.substring(0, part.indexOf('['));
int index = Integer.parseInt(part.substring(part.indexOf('[')+1, part.indexOf(']')));
tokens.add(new ArrayToken(fieldName, index));
} else {
tokens.add(new FieldToken(part));
}
};
return tokens.iterator();
}
}
abstract class Token {
protected final String fieldName;
Token(String fieldName) {
this.fieldName = fieldName;
}
public abstract Object value(Object value);
public abstract boolean accept(String key, Object value);
public abstract void update(Map.Entry<String, Object> entry, Object newValue);
}
class FieldToken extends Token {
FieldToken(String fieldName) {
super(fieldName);
}
@Override
public Object value(Object value) {
return value;
}
@Override
public boolean accept(String key, Object value) {
return fieldName.equals(key);
}
@Override
public void update(Map.Entry<String, Object> entry, Object newValue) {
entry.setValue(newValue);
}
}
class ArrayToken extends Token {
private final int index;
ArrayToken(String fieldName, int index) {
super(fieldName);
this.index = index;
}
@Override
public Object value(Object value) {
return ((List) value).get(index);
}
@Override
public boolean accept(String key, Object value) {
return fieldName.equals(key) && value instanceof List && ((List) value).size() > index;
}
@Override
public void update(Map.Entry<String, Object> entry, Object newValue) {
List list = (List) entry.getValue();
list.set(index, newValue);
}
}
JSON字符串可以使用Jackson轻松解析为映射:
Map<String,Object> userData = new ObjectMapper().readValue("{ \"store\": ... }", Map.class);
问题是您想要的功能已经是JsonPath的一个未文档化的功能。使用json结构的示例:
String json = "{ \"store\":{ \"book\":[ { \"category\":\"reference\", \"author\":\"Nigel Rees\", \"title\":\"Sayings of the Century\", \"price\":8.95 }, { \"category\":\"fiction\", \"author\":\"Evelyn Waugh\", \"title\":\"Sword of Honour\", \"price\":12.99, \"isbn\":\"0-553-21311-3\" } ], \"bicycle\":{ \"color\":\"red\", \"price\":19.95 } } }";
DocumentContext doc = JsonPath.parse(json).
set("$.store.bicycle.color", "green").
set("$.store.book[0].price", 9.5);
String newJson = new Gson().toJson(doc.read("$"));
问题内容: 我正在寻找一种在字符串中查找JSON数据的方法。像wordpress简码一样思考它。我认为最好的方法是使用正则表达式。我不想解析JSON,只需查找所有出现的事件。 正则表达式中是否有办法使括号的数量匹配?目前,当我嵌套对象时遇到了这个问题。 演示的快速示例: 结果,我想要两个JSON字符串。谢谢! 问题答案: 从给定的文本中提取JSON字符串 由于您正在寻找一种简单的解决方案,因此可以
下面是我的JSON: 我想用下面的规则更新上述JSON字符串的两个属性: 标志:我想盲目地将此属性更新为。 infoFlag:如果< code>info的< code>name属性为< code>null,那么我希望将< code>infoFlag更新为< code>true否则为< code>false,如果它为< code>not null。 因此,在用这些规则更新JSON之后,我希望将JSO
问题内容: 我想找到字符串中任何“特殊”字符首次出现的索引,如下所示: …除非那是无效的Python语法。当然,我可以编写一个模拟此行为的函数: 我也可以使用正则表达式,但两种解决方案似乎都有些过分。在Python中有什么“明智”的方法吗? 问题答案: 您可以将enumerate和next与生成器表达式一起使用,获取第一个匹配项,或者如果s中没有字符,则返回None: 如果没有匹配项,则可以将您想
问题内容: 如何在Java中验证JSON字符串?还是可以使用正则表达式解析它? 问题答案: 一个疯狂的主意,尝试解析它并捕获异常: 该代码使用org.json JSON API实现,该实现在github,maven和部分Android上可用。
我有一个json,它有一个标签“msg”。现在,如果搜索结果以json格式显示,那么这个标签就不存在了。当搜索结果为0时,这个标签的值为not found。 现在我想检查这个标签是否存在。那么如何做到这一点 以下是未找到记录时的json示例:
需要验证的字符串采用以下格式,严格来说它不是JSON,不能使用PHP的JSON编码过程进行验证。请注意,键中的%%是必需的。 当前正则表达式成功验证了上述内容: 有效示例:https://regex101.com/r/4y1uEu/1 无效示例(第二个值周围没有引号):https://regex101.com/r/4y1uEu/2 值需要支持其他字符,最好是任何字符,所以我将REGEX更改为 与此