如何在javascript中完全获取带有重复键的JSON
Posted
技术标签:
【中文标题】如何在javascript中完全获取带有重复键的JSON【英文标题】:How to get the JSON with duplicate keys completely in javascript 【发布时间】:2015-08-30 19:14:10 【问题描述】:我正在尝试从 url 获取 JSON,但在响应对象中删除了重复键。有没有办法在不删除重复键的情况下完全获取它?这是我的js代码
$('document').ready(function()
var s = $.getJSON("new.json");
console.log(s);
);
下面是我的new.json
"s": "wae",
"s": "asd"
但在控制台中,我得到的 json 对象如下
responseJSON: Object
s: "asd"
提前致谢
【问题讨论】:
唯一的方法是手动解析 JSON(例如,将 JSON 作为普通文本获取) 确实如此。您必须从头开始编写一个自定义 JSON 解析器(除非其他人已经发布了一个,但我并没有放弃任何示例,而且库推荐无论如何都是题外话)。对于 *** 来说,这可能过于宽泛。 【参考方案1】:如果您无法更改服务器响应,对于简单的 JSON 数据,您可以像文本一样请求 json,然后像字符串一样解析它:
var check = new RegExp('["\']([^\'"]*)[\'"][^:]*:[^"\']*["\']([^\'"]*)[\'"]',"g");
$.ajax(
url : "text.json",
dataType : "text",
success : function(data)
var newData = ;
data.replace(check,function(a,b,c)
if(typeof newData[b] == "undefined")
newData[b] = c;
else if(typeof newData[b] == "object")
newData[b].push(c);
else
var ca = newData[b];
newData[b] = [ca,c];
return a;
);
console.log(newData);
console.log($.parseJSON(data));
,
error : function(e,a)
console.log(e,a);
);
在此代码中newData
与您的 json 是:
"s": ["wae","asd"]
【讨论】:
【参考方案2】:JSON 对象中的键应该是唯一的。否则,具有值的最后一个键通常是请求该键时提供的键。具有相同的键也使得区分对象的属性变得更加困难。密钥的全部意义在于使其可访问和可用。
要解决这个问题,您总是可以:
更改 JSON 中的键
更改 JSON 以包含数组
"s": ["wae","asd"]
The javascript Object Notation (JSON) Data Interchange Format) (RFC7159) 说:
对象中的名称应该是唯一的。
在这种情况下应该必须理解为RFC 2119中指定的
RFC 7159 解释了为什么唯一键是好的: > 从某种意义上说,名称都是唯一的对象是可互操作的 > 接收该对象的所有软件实现都将同意 > 名称-值映射。当对象中的名称不是 > 独特的,接收此类对象的软件的行为是 > 不可预测。许多实现报告姓氏/值对 > 仅限。其他实现报告错误或无法解析 > 对象,一些实现报告所有的名称/值对, > 包括重复项。 > > 观察到 JSON 解析库在是否 > 或者它们是否使对象成员的顺序对调用可见 > 软件。行为不依赖于成员的实现 > 从某种意义上说,订购将是可互操作的 > 受这些差异的影响。应该这个词,或形容词“推荐”,意味着可能有 在特定情况下存在忽略特定情况的正当理由 项目,但必须仔细理解其全部含义 在选择不同的课程之前称重。
【讨论】:
虽然这都是很好的建议,但实际上并不能回答问题。 @Quentin 是的,但看起来他自己能够从示例中更改 JSON,而不是试图回答这个问题,我觉得尝试给出是没有害处的一个可以解决问题的良好实践的想法。上面的答案对于评论来说也相当大,并且会因缺乏格式而受到影响。 我刚刚给了一个样本。实际上我无法更改 JSON。我想知道是否可以在没有重复的情况下获取。从 cmets 我猜这是不可能的。 @Quentin ,@Craicerjack 谢谢【参考方案3】:JSON.parse()
无法做到这一点。我相信更现代的 ES 规范声明后续键会覆盖早期键。
但是,JSON 规范不允许这样的 JSON。还有其他的解析器和序列化器可以在 JavaScript 中生成和使用这样的 JSON。例如,您可以使用 SAX 样式的 JSON 解析器clarinet:
const clarinet = require('clarinet');
const parser = clarinet.parser();
const result = [];
parser.onkey = parser.onopenobject = k =>
result.push(key: k, value: null);
;
parser.onvalue = v =>
result[result.length - 1].value = v;
;
parser.write('"a": "1", "a": "2"').close();
console.log(result);
// [ key: 'a', value: '1' , key: 'a', value: '2' ]
如果您想知道如何在浏览器中使用require()
,请了解如何使用webpack。
【讨论】:
【参考方案4】:JSON 允许重复键,但 Javascript Objects
不允许。
因为键可以重复,这意味着 JSON 不能表示为基于键/值的字典,也不能直接转换为 Javascript Object
。
您必须“遍历”JSON 中的每个键/值对,然后按照您认为合适的方式对其进行处理。我不知道您要转换成什么结构,但只要它不是 Javascript Object
,就可以了。例如,您可能会遍历 JSON 对象并将值输出到 .ini
或 .css
文件,其中“键”可以重复。
JSON.parse()
将不起作用,因为它会尝试解析为不允许重复键的 Javascript Object
。如果密钥被重用,解决方案是简单地覆盖任何先前的值。但是,我们可以根据 JSON.parse()
的工作方式使用代码,而不是在 Javascript Object
上设置属性,您可以从那里拆分并应用您的自定义解决方案。
您可以修改完整的 JSON 解析器,例如 json2,或使用解析器在密钥到达时流式传输,例如 clarinet 或 Oboe.js。
【讨论】:
【参考方案5】:您可以尝试使用给定的结构多次使用相同的键:
[
"s": "wae",
"s": "asd"
]
正如 Craicerjack 所建议的,您还可以使用单个键为多个值使用数组:
"s": ["wae","asd"]
【讨论】:
谢谢阿文德。但我的问题是是否可以不更改 JSON。以上是关于如何在javascript中完全获取带有重复键的JSON的主要内容,如果未能解决你的问题,请参考以下文章