关于 javascript:重命名 JSON 属性,如果它们包含没有 JSON.stringify 的某个字符

Renaming JSON properties if they contain a certain character without JSON.stringify

我有一个独特的问题。我目前正在尝试将 JSON 数据源连接到剑道网格。因此,JSON 中的任何地方都不能有 #,因为它会与 kendo 混淆。所以我必须采取这样的数据:

1
2
3
4
[
    {"ID#":"1","Prop1":"Val1#"},
    {"ID#":"2","Prop2":"Val2"},
]

并转义 # 以便剑道能够理解它:

1
2
3
4
[
    {"ID\\#":"1","Prop1":"Val1\\#"},
    {"ID\\#":"2","Prop2":"Val2"},
]

最大的问题是 JSON 几乎可以像任何东西:可能有任意数量/名称的键/值。

我的尝试:

我试图像这样转义 #var dataSource = JSON.parse(result.replace("#","\\\\#")); 但是,当我尝试这样做时,JSON.parse 会引发错误:

SyntaxError: JSON.parse: bad escaped character at line 1 column 7 of the JSON data

然后我尝试将 # 替换为 #。事实证明,Kendo 只能支持行中的 HTML 实体,而不支持列标题中的 HTML 实体,而不会出现模板错误。所以我可以像这样替换属性值:

1
2
3
4
5
6
7
8
var dataSource = JSON.parse(result, function(key, value) {
       if(typeof value ==="string") {
           return value.replace("#","#");
       }
       else {
           return value;
       }
 });

这适用于价值观!但是,键仍然可能包含 #,这会弄乱我的剑道网格。我试图遍历每个对象和键/对,如果它有 # 则替换键,但由于某种原因,当我调用 Object.keys 时,返回的数组只是 0 和 1,即使这不是我的数据已命名。

1
2
3
4
5
6
7
8
9
10
11
12
13
for (var object in dataSource) {
     for (var property in object) {
          if (object.hasOwnProperty(property)) {
                var keys = Object.keys(object);
                for(var key in keys) {
                     var oldName = key;
                     var newName = key.replace("#","\\#");
                     object[newName] = object[oldName];      
                     delete object[oldName];          
                 }  
           }
      }
 }

上面的这部分似乎没有效果。它甚至不会抛出错误。

我还尝试将 # 替换为字符串:hashliteral。然后,在创建剑道网格后,我尝试使用 jQuery 将所有 hashliteral 替换为 #.

1
2
var fixed = $("#grid").html().replace(/hashliteral/g,"#");
$("#grid").html(fixed);

这确实有效,但它破坏了剑道网格和所有绑定。网格功能是必须的,所以我不能使用这个解决方案。

回顾一下

我正在尝试删除/替换或转义 JSON 数据中的所有 #,以便它与我的 Kendo Grid 一起正常运行。

  • 我不能使用 JSON.stringify 并将 # 替换为 \\\\# 因为 JSON.parse 失败。
  • 我不能使用 # 因为剑道标题不能有特殊字符。
  • 我不能使用 jQuery 来修改 $("#grid").html() 因为它破坏了网格绑定。
  • 关键可以是任何东西。该值也可以是任何值。
  • JSON 不是嵌套的或复杂的。
  • 我无法在 KendoGrid 列上定义字段/标题,因为我不知道字段/标题需要是什么,数据非常动态。

我已经准备好放弃这一点,只需从数据中删除所有 #。如果有人能想到某种方法来实现这一点:重命名一个对象的属性,以便所有 # 都以 \\ 开头,那将不胜感激。对于我的一生,我找不到解决这个问题的办法。


我认为您已经走在正确的Rails上,但是创建一个新的对象列表会更容易:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var newObjects = [];

for (var i = 0; i < dataSource.length; i++ ) {
    var currentObject = dataSource[i];
    var newObject = {};

    for (var key in currentObject) {
        if (currentObject.hasOwnProperty(key)) {
             var newKeyName = key.replace("#","__HASHLITERAL__");
             var newValue = currentObject[key];
             if(typeof newValue ==="string") {
                  newValue = newValue.replace("#","__HASHLITERAL__");
             }
             newObject[newKeyName] = newValue;
        }
    }

    newObjects.push(newObject);
}

console.log(newObjects);

希望对您有所帮助,我正确理解了您的问题。

编辑:您不能使用像 \\ 这样的特殊字符作为键,因此您必须实际使用像 ___something___ 这样的独特字符,然后您可以将其替换为以后的任何内容。