Почему json ведет себя так странно? - PullRequest
7 голосов
/ 21 января 2010

Есть ли какие-нибудь резервные слова для 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 ведет себя странным образом.
Я не определил "класс" как имя переменной, это просто ключ.

Проблема в том, что если аргумент указан как, "класс" это ключ или резерв слово, затем как я успешно вставил в Line#2, и если его может вставить в dimObject, то почему его не удалось вставить в finalObject .

Пожалуйста, помогите мне разгадать эту тайну

ТОЧНЫЙ КОД ::

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 ]

4 голосов
/ 21 января 2010

Что касается ваших наблюдений, JSON следует зарезервированным словам JavaScript (или ECMAScript, как его следует называть), и class является одним из них.

РЕДАКТИРОВАТЬ:

Хотя, играя с 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 на на этом сайте

2 голосов
/ 21 января 2010

Редактировать : В вашем примере вы пишете код на Java. Я не знаю, какую Java-реализацию JSON вы используете, но она, вероятно, не является строгой. Он не должен быть интерпретатором или движком JavaScript, поэтому он не мешает вам делать то, что вы не должны делать. Вот почему вы можете добавить ключ «класс», как вы сделали - сторона Java позволит вам сделать это, даже если это неправильно. Это не проверка, чтобы убедиться, что вы не используете ключевые слова в качестве идентификаторов. Когда этот JSON будет интерпретирован веб-браузером после того, как он покинет мир Java, у вас возникнут проблемы, потому что теперь это слово «класс» имеет особое значение.

class - зарезервированное слово. Вы должны избегать использования его в качестве имени переменной. См. здесь для списка зарезервированных слов.

Консоль 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"

Дело в том, что не используйте зарезервированные слова в качестве идентификаторов. Вы, вероятно, не получите ожидаемых результатов.

1 голос
/ 29 января 2010

Не думаю, что ваш минимальный пример правильно повторяет проблему, с которой вы столкнулись.

Используя библиотеку 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"]}}
1 голос
/ 27 января 2010

причина, по которой JSON использует { "double quotes":"around key/vals" }, именно по этой причине - для экранирования зарезервированных слов.

, которые говорят, что если вы получаете valid JSON, проблем быть не должно, так каклюбые зарезервированные слова будут экранированы "double quotes" ...

Я заметил, что у вас пропущена кавычка в этой строке:

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

должно быть "supplier".Есть ли в любом случае вы могли бы изменить это?или это генерируется автоматически?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...