如何使用 JSON.NET 使用十六进制编码字符解析格式错误的 JSONP?

Posted

技术标签:

【中文标题】如何使用 JSON.NET 使用十六进制编码字符解析格式错误的 JSONP?【英文标题】:How to parse malformed JSONP with hex-encoded characters using JSON.NET? 【发布时间】:2012-09-03 22:55:33 【问题描述】:

我这样调用 google 的字典 api:

var json = new WebClient().DownloadString(string.Format(@"http://www.google.com/dictionary/json?callback=dict_api.callbacks.id100&q=0&sl=en&tl=en", "bar"));

但是我得到的响应是此代码无法正确解析:

json = json.Replace("dict_api.callbacks.id100(", "").Replace(",200,null)", "");
JObject o = JObject.Parse(json);

解析在遇到这个时死亡:

"entries":["type":"example","terms":["type":"text","text":"\x3cem\x3ebars\x3c/em\x3e of sunlight shafting through the broken windows","language":"en"]]

\x3cem\x3ebars\x

stuff 杀死了解析

有没有办法用 JSON.NET 处理这个 JSONP 响应?

aquinas aquinas 对另一个“Parse JSONP”问题的answer 显示了很好的正则表达式x = Regex.Replace(x, @"^.+?\(|\)$", ""); 来处理JSONP 部分(可能需要针对这种情况调整正则表达式),所以这里的主要部分是如何处理十六进制- 编码字符。

【问题讨论】:

【参考方案1】:

参考:How to decode html encoded character embedded in a json string

字符串的 JSON 规范不允许十六进制 ASCII 转义序列,但只允许 Unicode 转义序列,这就是转义序列无法识别的原因,这也是为什么使用 \u0027 应该可以工作的原因......现在你可以盲目地替换 \ x 与 \u00 (这应该完全适用于有效的 JSON,尽管理论上某些 cmets 可能会损坏,但谁在乎......:D)

所以把你的代码改成这样就可以解决问题了:

        var json = new WebClient().DownloadString(string.Format(@"http://www.google.com/dictionary/json?callback=dict_api.callbacks.id100&q=0&sl=en&tl=en", "bar"));

        json = json
                .Replace("dict_api.callbacks.id100(", "")
                .Replace(",200,null)", "")
                .Replace("\\x","\\u00");

        JObject o = JObject.Parse(json);

【讨论】:

【参考方案2】:

服务器未返回有效的 JSON:JSON 支持\xAB 字符转义序列,仅支持\uABCD 转义序列。

我见过的“解决方案”首先在字符串上执行文本替换。这是我的replies to a similar questions for Java 之一。注意底部的正则表达式inputString.replaceAll("\\x(\d2)", "\\u00$1");适应语言。

【讨论】:

以上是关于如何使用 JSON.NET 使用十六进制编码字符解析格式错误的 JSONP?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Json.NET 反序列化高精度十进制值?

如何修改从使用 Json.Net 序列化数据集获得的 JSON 以用于 ESRI 地理编码

如何在 PHP 中解压缩二进制字符串?

基于哈夫曼树的任意文件解压缩实现

如何从 base 64 编码字符串中获取十六进制块?

如何在 Python 3.2 或更高版本中使用“十六进制”编码?