代码之家  ›  专栏  ›  技术社区  ›  Ashish Agarwal

为什么JSON的行为如此怪异?

  •  7
  • Ashish Agarwal  · 技术社区  · 16 年前

    JSON是否有保留字作为密钥?

    我的JSON结构是

    dimObject{String:String}
    finalObject(String:dimObject}
    
    Line1# JSONObject dimObject=new JSONObject()
    Line2# dimObject.put("class",["A","B","c"]);
    Line3# dimObject.put("name",["sam"]);
    Line4# System.out.print("dimObject#"+dimObject.toString());
    Line5# JSONObject finalObject=new new JSONObect();
    Line6# finalObject("supplier",dimObject);
    Line7# System.out.print("finalObject#"+finalObject.toString());
    

    输出:

    dimObject#{"class":["A","B","c"],"name":["sam"]}
    finalObject#{"supplier":{"name":["sam"]}}
    

    所以问题是为什么我的JSON行为怪异。
    我没有将“class”定义为变量名,它只是一个键。

    问题是,如果一个参数是这样给出的,“类”是 钥匙或备用 单词然后 怎样 我成功插入 Line#2 如果它的 可插入的 在DimObject中,为什么 无法在finalObject中插入able .

    请帮我解开这个谜

    确切代码:

    public JSONObject getRequiredAttributesWithValues() {
            List<UserConstraint> constraintList = new ArrayList<UserConstraint>();
            Map<String, FactTableOptimizingInfo> factTableMap = MappingInfo.INSTANCE.
                    getFactTableUserNameToFactTableOptimizingInfoMap();
            Map<String, DimensionTableInfo> dimTableMap = MappingInfo.INSTANCE.getDimTableRealNameToObjectMap();
            JSONObject requiredAttributes = getRequiredAttributes();
            JSONObject finalObject = new JSONObject();
            for (Object dimName : requiredAttributes.keySet()) {
                JSONObject dimObject = new JSONObject();
                JSONArray colNames = requiredAttributes.getJSONArray((String) dimName);
                for (Object colName : colNames) {
                    List<String> columnList = new ArrayList<String>();
                    String dimensionName = (String) dimName;
                    String columnName = (String) colName;
                    constraintList = new ArrayList<UserConstraint>();
                    for (FilterDataStructure filter : this.info.getGlobalFilterList()) {
                        if (filter.getDimName().equals(dimensionName)) {
                            if (filter.getColumnName().equals(columnName)) {
                                AtomicConstraint.ConstraintType type;
                                try {
                                    Integer.parseInt(filter.getValue());
                                    type = AtomicConstraint.ConstraintType.INTEGER_TYPE;
                                } catch (NumberFormatException e) {
                                    type = AtomicConstraint.ConstraintType.STRING_TYPE;
                                }
                                UserConstraint constraint = new UserAtomicConstraint(dimensionName, columnName, 
                                                            AtomicConstraint.getStringToOperator(filter.getOperator()),
                                                            filter.getValue(), type, factTableMap, dimTableMap);
                                constraintList.add(constraint);
                            }
                        }
                    }
    
                    columnList.add(columnName);
                    List<UserDimensionInfoToBuildQuery> dimList = new ArrayList<UserDimensionInfoToBuildQuery>();
                    UserTableAndColInfo groupByInfo = new UserTableAndColInfo(dimensionName, columnName);
                    ArrayList<UserTableAndColInfo> groupByInfoList = new ArrayList<UserTableAndColInfo>();
                    groupByInfoList.add(groupByInfo);
    
                    UserDimensionInfoToBuildQuery dim = new UserDimensionInfoToBuildQuery(dimensionName, columnList);
                    dimList.add(dim);
                    UserInfoToBuildQuery.Builder queryBuilder = new UserInfoToBuildQuery.Builder(dimList).
                            groupBy(groupByInfoList);
                    if (constraintList != null && !(constraintList.isEmpty())) {
                        if (constraintList.size() > 1) {
                            queryBuilder = queryBuilder.constraints(new UserComplexConstraint(constraintList,
                                    ComplexConstraint.Joiner.AND));
                        } else {
                            queryBuilder = queryBuilder.constraints(constraintList.get(0));
                        }
                    }
                    List<Object> result = (List<Object>) DataAccessor.getData(queryBuilder.build());
                    if (result == null) {
                        continue;
                    }
                    JSONArray valueArray = new JSONArray();
    
                    for (Object row : result) {
                        List<Object> splitRow = (List<Object>) row;
                        valueArray.add(splitRow.get(0).toString());
                    }
                    dimObject.put(colName, valueArray);
                }
                finalObject.put(dimName, dimObject);
            }
            return finalObject;
        }
    }
    
    4 回复  |  直到 14 年前
        1
  •  4
  •   Anthony Forloney    16 年前

    至于后续观察,json遵循javascript(或应称为ecmascript)保留字和 是其中之一。

    编辑:

    当你尝试使用javascript时,你似乎可以在引号内使用保留字,我测试了它,如下所示:

    myObj = {"class" : "Analysis of Algorithms"}; // <--works
    myObj = { class  : "Analysis of Algorithms"}; //  <--works
    myObj = { class  : "class"}; // <--works
    myObj = {"class" :  class }; // <--does not work.
    

    而且很有趣,我仍然对这个问题感到困惑。使用JSON,我将所有的技术都用于JavaScript,因此我无法产生与您相同的结果。

    我找到的源文件 JSONObject.java this website

        2
  •  2
  •   Jonathon Faust    16 年前

    编辑 在你的例子中,你正在用Java编写代码。我不知道你使用JSON的Java实现,但它可能并不严格。它不应该是一个JavaScript解释器或引擎,所以它不会阻止你做一些你不应该做的事情。这就是为什么你可以像你那样添加“类”键——Java端会让你这样做,即使它是错误的。它不会检查以确保您没有使用关键字作为标识符。当JSON在离开Java世界之后被Web浏览器解释时,就会出现问题,因为现在“类”字具有特殊含义。

    class 是保留字。您应该避免将它用作变量名。见 here 保留字列表。

    Chrome的javascript控制台允许我将其用作标识符。IE8表现不同。我不能用点符号,但我可以用括号符号。见 a.class a['class'] 在下面。

    >>var class = "1"
      "Expected identifier"
    >>var a = "1"
    undefined
    >>a
    "1"
    >>class
      "Syntax error"
    >>var a = {}
    undefined
    >>a["foo"] = "1"
    "1"
    >>a["class"] = "2"
    "2"
    >>a.class
      "Expected identifier"
    >>a.foo
    "1"
    >>a['foo']
    "1"
    >>a['class']
    "2"
    

    关键是,不要使用保留字作为标识符。你可能得不到你期望的结果。

        3
  •  1
  •   Dan Beam    16 年前

    JSON使用的原因 { "double quotes":"around key/vals" } 正是因为这个原因-为了逃避保留字。

    也就是说,如果你 有效的 json,应该没有问题,因为任何保留字都将由 "double quotes"

    我注意到这一行中有一个缺少的引号:

    finalObject#{"supplier:{"name":["sam"]}}
    

    应该是 "supplier" . 你能换一下吗?或者它是自动生成的?

        4
  •  1
  •   Yoni    16 年前

    我不认为你的最小例子正确地复制了你正在经历的问题。

    使用JSON Java库 json.org 我运行了这个Java代码:

    public static void main(String[] args) throws JSONException {
        JSONObject dimObject=new JSONObject();
        dimObject.put("class",new JSONArray(new String[] {"A","B","c"}));
        dimObject.put("name", "sam");
        System.out.println("dimObject#"+dimObject.toString());
        JSONObject finalObject=new JSONObject();
        finalObject.put("supplier",dimObject);
        System.out.println("finalObject#"+finalObject.toString());
    }
    

    产出如预期:

    dimObject#{"name":"sam","class":["A","B","c"]}
    finalObject#{"supplier":{"name":"sam","class":["A","B","c"]}}