【问题标题】:Finding it difficult to process JSON in delphi发现很难在 delphi 中处理 JSON
【发布时间】:2012-12-17 10:21:00
【问题描述】:

我目前正在开发一个应用程序,该应用程序将从《魔兽世界》军械库中获取你的角色数据。 示例字符:My WoW Character(link)

我将通过调用暴雪提供的 API 来获得我想要的所有信息,我将在JSON 中获得响应。 示例JSONJSON response for the character above(link)

起初我尝试通过字符串操作从JSON 获取数据。 这意味着,拆分我的字符串,在字符串中搜索关键字以找到位置并将其格式化为单独的数据片段,例如才能和统计数据。

这在开始时效果很好,但随着我想要更多数据,这变得更加困难,因为我在所有字符串上运行了许多函数,它变得非常模糊,不清楚当时我在做什么。

有没有处理我的JSON 的好方法? 我正在考虑获取JSON 并创建一个空类。 在处理JSON 时,它会生成属性并将值存储在其中。 但我不知道是否以及如何动态生成属性。

将来我想获得更多数据,但首先我想先启动并运行它,然后再考虑。

有人对此有任何想法/建议吗?

提前致谢。

【问题讨论】:

  • 查看 Delphi JSON library for XE2 available for object serialization 了解不同的 Delphi 库以解析 json
  • 我想你可以试试TJSONObjectSuperObject 之类的库。
  • @Teun 算了。 Henri 通常忙于他最近的项目并放弃已完成的项目。此外,如果他希望更详细地解释基础知识,他不会在私人邮件中讨论它,而是会为每个人创建和发布更详细的文档。所以你最好去谷歌搜索“如何使用 SuperObject 做这个和那个”,而不是认为 Henrui 会向你个人解释。您也可以尝试一些其他库,例如 Synopse,其论坛通常比 Henri 的更活跃。
  • 如果您有企业级 Delphi - 那么它可能是真的。但我认为 DB-Express 是一个重量级的平台,它不需要依赖并用于快速解析。但这当然是你的选择。
  • “我是 Delphi 的新手,从 2012 年 1 月 10 日才开始使用它,所以” 1) 我可以要求不要在国际网站上使用这种日期格式吗?感谢美国,如果您的意思是 01-10-2012 或 10-01-2012 // 2) 您以前从未使用过 hDelphi,这有点模棱两可?如果是这样,那你为什么开始呢? delphi小众是一个普遍的观点,没有“新鲜血液”进入,所以学习反例很有趣。

标签: json delphi api delphi-xe3 world-of-warcraft


【解决方案1】:

您的 JSON 看起来相当简短和基本。您似乎不需要特殊的速度或异国情调的功能。 http://jsonviewer.stack.hu/#http://eu.battle.net/api/wow/character/moonglade/Xaveak?fields=stats,talents

虽然自从 Delphi XE2 以来,您确实将 JSON 解析器作为 DB-Express 套件的一部分,但仍然存在一些问题:
1. 被告知会导致速度和可靠性问题。
2. 它会让你的程序依赖于 DB-Express 包(为什么,如果你没有真正使用它来访问数据库?) 3. 它将您的未来绑定到 Delphi 企业版。

所以你最好尝试一些 3rd-party 库。

其中一个最快的可能是 Synopse JSON 解析器,他们的 mORMot library 的副项目。它通常是很好的代码,非常注重速度,开发人员在他们的论坛上积极提供帮助。

Henri Gourvest 的 SuperObject 是一个更广为人知和使用的库。 它声称 Delphi 是 the fastest parser,虽然由于上述原因,这可能不再正确,但对于大多数任务来说,速度已经足够了。 Henri 本人并没有积极支持他的前项目,总是在做一些新的事情,所以the scarce documentation(也在安装包中重复)将是你正式拥有的全部,加上there is a forum 其他用户可能会帮助你。 OTOH SuperObject 设计背后的主要思想是统一性,虽然某些任务确实可以更好地记录 - 这主要是由于不确定性“如果这项任务真的可以在没有任何特殊处理的情况下以统一的方式工作”。但通常它确实如此。
PS。由于那是 wiki,您可以尝试为未来的用户增强它;-)

所以回到文档,你需要

1) 将整个 JSON 加载到库中。您可以通过 http 库创建 TStream 或提供带有数据的字符串缓冲区来做到这一点:即 the manual

解析 JSON 数据结构部分

2) 读取诸如“名称”和“级别”之类的值 - 在 如何读取对象的属性值? 部分中进行了描述。

3) 征用诸如“人才”之类的数组 - 在浏览数据结构部分中进行了描述。

【讨论】:

  • 谢谢你,我现在知道它是一个小 JSON。不过看你能加什么,大部分我会加link 可以变得相当大;)
  • 使用 Synapse 的组件和库不会出错。他们的支持和奉献超出了这个世界。
  • @LeonardoHerrera synOpse 不是 synApse - 两个完全不同的房子和库
  • @Arioch'The - 是的,你完全正确,那是一个错字。我指的是 Arnaud 的项目思想(mormot / Synopse。)
【解决方案2】:

XE3 具有“内置”JSON 支持(请参阅docwiki),但我听说(我自己没有使用过)它没有得到很好的优化。 所以也许寻找一些第三方选项,如SuperObject

【讨论】:

    【解决方案3】:

    使用包含在我的delphi-oop 库中的TSvSerializer 可以轻松完成您的任务。您只需要声明您的模型类型并从您的 json 字符串中反序列化它。您的模型(非常简化的不完整且未经测试的版本)应如下所示:

    type
      TStats = class
      public
        property health: Integer read fhealth write Fhealth;
        ... 
      end;
    
      TTalent = class
      public
        property tier: Integer read Ftier write Ftier;
        ...
      end;
    
      TMainTalent = class
      public
        property selected: Boolean read Fselected write Fselected;
        property talents: TObjectList<TTalent> read Ftalents write Ftalents;
      end;
    
      TWowCharacter = class
      public
        property lastModified: Int64 read FlastModified write FlastModified;
        property name: string read Fname write Fname;
        ...
        property stats: TStats read Fstats write Fstats;
        property talents: TObjectList<TMainTalent> read Ftalents write Ftalents;
        ...
      end;
    

    那么你只需要这样做:

    uses
      SvSerializer;
    
    var
      LWowCharacter: TWowCharacter;
    begin
      LWowCharacter := TWowCharacter.FromJson(YourJsonString);
    ...
    

    你可以在delphi-oop项目中找到我的联系邮箱,如果有什么不清楚的地方可以问我,我会在空闲时间帮助你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-19
      • 2016-08-01
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 2022-01-04
      相关资源
      最近更新 更多