为什么都反对 XML 而支持使用 JSON?

论坛 期权论坛 期权     
林凌宇   2018-10-20 23:02   6949   6
分享到 :
0 人收藏

6 个回复

倒序浏览
2#
money os  4级常客 | 2018-10-20 23:02:08 发帖IP地址来自
要是两个储存html字符串的时候都不要转义就好了=。=
3#
超越数排排  2级吧友 | 2018-10-20 23:02:12 发帖IP地址来自
XML自带DDL,可以保存schema和数据,JSON一般只负责数据。如果已经有schema用JSON在数据表示上会简洁友好一些。
4#
绍毅  3级会员 | 2018-10-20 23:02:13 发帖IP地址来自
2014年11月14日,删除过激的话,并修正语法问题.
      JSON 的 完整名字是是 javascript object notation , 翻译过来就是js的对象标记格式。xml是 extends makeup language,翻译过来就是扩展性标记语言。在网页上主要的脚本语言是js,JSON是JS是能够直接把JSON当成对象数组来使用的,使用起来非常方便,而且对于数组能够直接转化,而不用去经行转化的.XML虽然在JS中能使用,但使用起来的非常地不方便,举个例子如下:
问题:获取 "FuShiApple"这种水果商品 的生产国家属性值,
  • XML例子
  1. 文件名为: abc/水果商品属性.xml            China        GuangDong        ...        ...        ...   
复制代码
首先JavaScript 语言中,首先你要把文件载入到变量A中,然后对变量A获取FuShiApple这个元素并存入到变量B,接着对变量B获取country属性值.其代码是:
  1. function getFuShiAppleCountry{xmlDoc=loadXMLDoc(" abc/水果商品属性.xml");fuShiApple=xmlDoc.getElementsByTagName("FuShuApple")[0];for(x in fuShiApple){var country = fuShiApple.getElementByTagName("country")[x];for(count in country){document.write(country[count].childNodes));}}}
复制代码
2. JSON
  1. [FuShiApple {country:China,ProductProvince:GuangDong,price:..,..}]
复制代码
它的使用方法就只有一句话  FuShiApple.country 就可以获取到country 值了.
从上面的实现方法中,可以看出JSON 能够直接转化成Js对象的先天好处了吧. 所以要是能用JSON的地方,强烈建议用JSON来操作对象.
5#
jacky yang  3级会员 | 2018-10-20 23:02:14 发帖IP地址来自
php json转数组快
6#
匿名用户   | 2018-10-20 23:02:15 发帖IP地址来自
提示: 作者被禁止或删除 内容自动屏蔽
7#
Misaka Mikoto  4级常客 | 2018-10-20 23:02:16 发帖IP地址来自
我从另外一个角度解释一下为什么我支持json,
因为 json 格式更适合流式的代码生成,在生成 json 时只需关心自己,无需考虑它的父级或者 key,这什么意思呢?
   比如有一个 C++ 的数据结构,我现在要把它的定义导出成定义字符串到文件以便让 lua 在没有 C++ 定义的情况也可以临时处理二进制协议流( iOS 不能自动更新可执行文件但是可以更新资源大家都懂的),这个数据结构可以很复杂,某个字段可能嵌套很多层,也有可能只是一个简单类型,假设是这样的吧 :
  1. struct ClassA : Serializable{  enum class EA : uint16_t  {    EA_1, EA_2  }  int8_t i8;  EA  ea;}struct ClassB : Serializable{  float                 f;  ClassA         clsA;  std::vector vmib;}
复制代码

Serializable 经过了特殊处理(一堆模版和宏)可以让 C++ 编译器自动对它的派生类生成序列化代码,也就是在内存里是有所有它的派生类的字段类型和描述的 tree 结构的。

如果采用 json 作为输出格式的话,在生成 ClassB 定义时可以这样
  1. {  "protocolName" : "ClassB",  "members": [    {      "name": "f",      "type": "float"    },    {      "name": "clsA",      "type": "protocol",      "protocolInfo": {        // classA 的嵌套定义        ...      }    },    ... ]}
复制代码
在遍历时,在 ClassB 的字段遍历器给某个字段生成了 key 之后,不需要考虑它的具体定义是什么,可以直接调用对应的类型处理函数(负责这种类型数据的序列化反序列化及各种查询操作等)来生成类型定义,比如第二个 clsA 字段,在字段遍历器生成到 "type": 后,调用 ClassA  类型对应的类型处理函数,这个处理函数首先填上 "protocol",但是因为它是嵌套类型,它立刻又添加了 "protocolInfo":的 key ,然后继续调用 ClassA 的定义生成函数(它会调用自己的字段遍历器),可以无限递归,然后当生成完毕后立刻就可以返回上层,对上层也没有影响,上层的字段遍历器如果还要对这个字段添加其它 key 都没问题。

如果采用 xml 格式呢,有两种方案,
第一种是将所有属性都用子节点的方式来定义:
  1.       clsA                 protocol               ....      
复制代码

  这里就遇到一个麻烦问题了,考虑到可递归性起始标签必须由字段遍历器生成,但是在生成 clsA 这个字段的时候,由于类型处理函数需要附加其它字段,它需要立即关闭,但是这个标签是上一级开启的, 类型处理函数返回后上一级必须关闭这个标签,可是再关闭一次就出现标签配对错误了(lua 的 parser 也有类似问题,即一个 FuncState 如何判断在 leavefunction 前是否已经生成了 return 的字节码,lua 的解决办法是无论函数内的 statement 是否有 return 指令, FuncState 在返回之前都添加一个 return 指令,虽然会造成指令冗余,但是并不会造成什么问题;但 xml 就无法这么做,因为它的节点闭合需要写跟节点开启同样的名字,这就蛋碎了,而 json 都写 "}" 就万事大吉了)。

第二种是把数据作为属性的方式定义,但是这样会碰到无法把 type 节点作为 的属性的问题,因为出现了节点的右括号由谁关闭的矛盾。

也许你会说使用生成 dom 的方式可以解决这个问题,但是我就为了输出一堆字符串你跟我说要引入 dom 库这么重的东西?r u serious?

一句话总结:XML 的节点开启和闭合必须使用同样的名字,所以子节点处理函数无法关闭父节点,但 json 所有的 block 关闭都是 "}",所以可以随心所欲的关闭, 我爱 json, json 不知爱不爱我。

结论:xml 不适合用流式输出字符串的方式来生成。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP