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"}]}]}}