JSON 的点符号(包括数组)
Dot notation to JSON (including arrays)
我想将点符号字符串转换为 JSON 对象,但也包括数组,例如:我想将 first.second[0].third[0].fourth
设置为 some string
。所以,JSON 必须是:
{
"first": {
"second": [
{
"third": [
"fourth": "some string"
]
}
]
}
}
我找到 然后编辑,结果是这样的:
private void expand(Object parent, String key, String value) {
if (key == null) return;
if (!key.contains(".") && !key.contains("[")) {
if (parent instanceof JSONObject) {
((JSONObject) parent).put(key, value);
} else {
((JSONArray) parent).put(value);
}
return;
}
String innerKey = key.substring(0, key.contains(".") ? key.indexOf(".") : key.length());
String formattedInnerKey = innerKey.contains("[") ? innerKey.substring(0, innerKey.indexOf("[")) : innerKey;
String remaining = key.contains(".") ? key.substring(key.indexOf(".") + 1) : key.contains("]") ? key.substring(key.indexOf("]") + 1) : null;
if (parent instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) parent;
if (jsonObject.has(formattedInnerKey)) {
expand(jsonObject.get(formattedInnerKey), remaining, value);
return;
}
} else {
JSONArray jsonArray = (JSONArray) parent;
Matcher matcher = Pattern.compile("(?<=\[)([^\]]+)(?=\])").matcher(innerKey);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find a index number in \"%s\"", innerKey));
int index = Integer.parseInt(matcher.group());
System.out.print(index + " - ");
if (!jsonArray.isNull(index)) {
System.out.print(jsonArray.get(index));
expand(jsonArray.get(index), remaining, value);
return;
}
}
Object obj = innerKey.contains("[") ? new JSONArray() : new JSONObject();
if (parent instanceof JSONObject) {
((JSONObject) parent).put(formattedInnerKey, obj);
} else {
JSONObject base = new JSONObject();
base.put(formattedInnerKey, obj);
Matcher matcher = Pattern.compile("(?<=\[)([^\]]+)(?=\])").matcher(innerKey);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find a index number in \"%s\"", innerKey));
int index = Integer.parseInt(matcher.group());
((JSONArray) parent).put(index, base);
}
expand(obj, remaining, value);
}
这个方法 - 有点 - 可行,但问题是它向数组添加元素而不是放置。我希望能够将对象放入该数组的索引中。我该如何解决这个问题?
解决方法如下:
public void expand(Object parent, String key, Object value) {
JSONElement element = new JSONElement(parent);
if (!key.contains(".")) { // End
element.put(key, value);
return;
}
String innerKey = key.substring(0, key.indexOf("."));
String remaining = key.substring(key.indexOf(".") + 1);
if (element.has(innerKey)) {
expand(element.get(innerKey), remaining, value);
return;
}
Object object = element.newInstance();
Object put = element.put(innerKey, object);
expand(put, remaining, value);
}
JSONElement class:
import com.google.common.base.Preconditions;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JSONElement {
private static final Pattern pattern = Pattern.compile("(?<=\[)([^]]+)(?=])");
private final Object base;
public JSONElement(Object base) {
Preconditions.checkNotNull(base, "base");
Preconditions.checkState(base instanceof JSONObject || base instanceof JSONArray, "base must be a JSONObject or JSONArray instead of " + base.getClass().getSimpleName());
this.base = base;
}
public Object put(Object key, Object value) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
if (keyAsString.contains("[")) {
String formatKey = keyAsString.contains("[") ? keyAsString.substring(0, keyAsString.indexOf("[")) : keyAsString;
JSONArray array = ((JSONObject) base).has(formatKey) ? ((JSONObject) base).getJSONArray(formatKey) : new JSONArray();
int index = getIndex(keyAsString);
array.put(index, value);
((JSONObject) base).put(formatKey, array);
return ((JSONArray) ((JSONObject) base).get(formatKey)).get(index);
}
((JSONObject) base).put(keyAsString, value);
return ((JSONObject) base).get(keyAsString);
}
int index = getIndex(keyAsString);
((JSONArray) base).put(index, value);
return ((JSONArray) base).get(index);
}
public boolean has(Object key) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
JSONObject object = (JSONObject) base;
String formatKey = formatKey(keyAsString);
if (keyAsString.contains("["))
return object.has(formatKey) && !object.getJSONArray(formatKey).isNull(getIndex(keyAsString));
return object.has(formatKey);
}
return !((JSONArray) base).isNull(getIndex(keyAsString));
}
public Object get(Object key) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
JSONObject object = (JSONObject) base;
String formatKey = formatKey(keyAsString);
if (keyAsString.contains("["))
return object.getJSONArray(formatKey).get(getIndex(keyAsString));
return object.get(formatKey);
}
return ((JSONArray) base).get(getIndex(keyAsString));
}
public Object newInstance() {
return base instanceof JSONObject ? new JSONObject() : new JSONArray();
}
private int getIndex(String key) {
Matcher matcher = pattern.matcher(key);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find an index number in \"%s\"", key));
return Integer.parseInt(matcher.group());
}
private String formatKey(String key) {
return key.contains("[") ? key.substring(0, key.indexOf("[")) : key;
}
}
用法:
JSONObject jsonObject = new JSONObject();
expand(jsonObject, "first.second[0].third[0].fourth", "some string");
System.out.println(jsonObject.toString()); // Prints: {"first":{"second":[{"third":[{"fourth":"some string"}]}]}}
我想将点符号字符串转换为 JSON 对象,但也包括数组,例如:我想将 first.second[0].third[0].fourth
设置为 some string
。所以,JSON 必须是:
{
"first": {
"second": [
{
"third": [
"fourth": "some string"
]
}
]
}
}
我找到
private void expand(Object parent, String key, String value) {
if (key == null) return;
if (!key.contains(".") && !key.contains("[")) {
if (parent instanceof JSONObject) {
((JSONObject) parent).put(key, value);
} else {
((JSONArray) parent).put(value);
}
return;
}
String innerKey = key.substring(0, key.contains(".") ? key.indexOf(".") : key.length());
String formattedInnerKey = innerKey.contains("[") ? innerKey.substring(0, innerKey.indexOf("[")) : innerKey;
String remaining = key.contains(".") ? key.substring(key.indexOf(".") + 1) : key.contains("]") ? key.substring(key.indexOf("]") + 1) : null;
if (parent instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) parent;
if (jsonObject.has(formattedInnerKey)) {
expand(jsonObject.get(formattedInnerKey), remaining, value);
return;
}
} else {
JSONArray jsonArray = (JSONArray) parent;
Matcher matcher = Pattern.compile("(?<=\[)([^\]]+)(?=\])").matcher(innerKey);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find a index number in \"%s\"", innerKey));
int index = Integer.parseInt(matcher.group());
System.out.print(index + " - ");
if (!jsonArray.isNull(index)) {
System.out.print(jsonArray.get(index));
expand(jsonArray.get(index), remaining, value);
return;
}
}
Object obj = innerKey.contains("[") ? new JSONArray() : new JSONObject();
if (parent instanceof JSONObject) {
((JSONObject) parent).put(formattedInnerKey, obj);
} else {
JSONObject base = new JSONObject();
base.put(formattedInnerKey, obj);
Matcher matcher = Pattern.compile("(?<=\[)([^\]]+)(?=\])").matcher(innerKey);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find a index number in \"%s\"", innerKey));
int index = Integer.parseInt(matcher.group());
((JSONArray) parent).put(index, base);
}
expand(obj, remaining, value);
}
这个方法 - 有点 - 可行,但问题是它向数组添加元素而不是放置。我希望能够将对象放入该数组的索引中。我该如何解决这个问题?
解决方法如下:
public void expand(Object parent, String key, Object value) {
JSONElement element = new JSONElement(parent);
if (!key.contains(".")) { // End
element.put(key, value);
return;
}
String innerKey = key.substring(0, key.indexOf("."));
String remaining = key.substring(key.indexOf(".") + 1);
if (element.has(innerKey)) {
expand(element.get(innerKey), remaining, value);
return;
}
Object object = element.newInstance();
Object put = element.put(innerKey, object);
expand(put, remaining, value);
}
JSONElement class:
import com.google.common.base.Preconditions;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JSONElement {
private static final Pattern pattern = Pattern.compile("(?<=\[)([^]]+)(?=])");
private final Object base;
public JSONElement(Object base) {
Preconditions.checkNotNull(base, "base");
Preconditions.checkState(base instanceof JSONObject || base instanceof JSONArray, "base must be a JSONObject or JSONArray instead of " + base.getClass().getSimpleName());
this.base = base;
}
public Object put(Object key, Object value) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
if (keyAsString.contains("[")) {
String formatKey = keyAsString.contains("[") ? keyAsString.substring(0, keyAsString.indexOf("[")) : keyAsString;
JSONArray array = ((JSONObject) base).has(formatKey) ? ((JSONObject) base).getJSONArray(formatKey) : new JSONArray();
int index = getIndex(keyAsString);
array.put(index, value);
((JSONObject) base).put(formatKey, array);
return ((JSONArray) ((JSONObject) base).get(formatKey)).get(index);
}
((JSONObject) base).put(keyAsString, value);
return ((JSONObject) base).get(keyAsString);
}
int index = getIndex(keyAsString);
((JSONArray) base).put(index, value);
return ((JSONArray) base).get(index);
}
public boolean has(Object key) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
JSONObject object = (JSONObject) base;
String formatKey = formatKey(keyAsString);
if (keyAsString.contains("["))
return object.has(formatKey) && !object.getJSONArray(formatKey).isNull(getIndex(keyAsString));
return object.has(formatKey);
}
return !((JSONArray) base).isNull(getIndex(keyAsString));
}
public Object get(Object key) {
String keyAsString = String.valueOf(key);
if (base instanceof JSONObject) {
JSONObject object = (JSONObject) base;
String formatKey = formatKey(keyAsString);
if (keyAsString.contains("["))
return object.getJSONArray(formatKey).get(getIndex(keyAsString));
return object.get(formatKey);
}
return ((JSONArray) base).get(getIndex(keyAsString));
}
public Object newInstance() {
return base instanceof JSONObject ? new JSONObject() : new JSONArray();
}
private int getIndex(String key) {
Matcher matcher = pattern.matcher(key);
Preconditions.checkState(matcher.find(), String.format("Matcher couldn't find an index number in \"%s\"", key));
return Integer.parseInt(matcher.group());
}
private String formatKey(String key) {
return key.contains("[") ? key.substring(0, key.indexOf("[")) : key;
}
}
用法:
JSONObject jsonObject = new JSONObject();
expand(jsonObject, "first.second[0].third[0].fourth", "some string");
System.out.println(jsonObject.toString()); // Prints: {"first":{"second":[{"third":[{"fourth":"some string"}]}]}}