用代数数据类型来parse json

s
shuaide
楼主 (未名空间)


下面是一个test case,parse一个json file。必须提供json schema, 可以在compile time的时候提示所有可能的类型结果和autocomplete。直接把整个json看成是一个
object,然后查key是否存在的方案不考虑(不然我就直接用python了)
https://stackoverflow.com/questions/59919496/how-to-parse-json-file-with-
type-composition-of-stdoptional-and-stdvariant
https://stackoverflow.com/questions/59903779/how-to-parse-json-with-field-of-optional-variant-in-haskell
https://www.reddit.com/r/haskell/comments/etmgre/how_to_parse_json_with_
field_of_optional_variant/

其实都是问同一个问题,parse 同一个json,链接里分别提供一个boiler plate可以直接上手。
感觉scala的algebraic data type还不如
haskell强,如果c++搞不出来,感觉scala估计也不好搞?所以直接上haskell。如果有java 大牛能parse这个json,那就太厉害了。

动态语言虽然直接支持variant type,但是后续处理会需要大量pattern matching,在runtime的时候查existence of key.目前需要处理的business requirement不考虑使用动态语言

如果现有的json parser都解决不了这个问题,我看是不是要自己写一个json parser
library
看到这里有个半成品:https://gist.github.com/willkill07/76268e7a88136705f7c2ea9177897cf1

p
pptwo

这种为啥不能用rapidjson的dom模式?我觉得sax模式都可以用。

【 在 shuaide (卖火柴的小女孩) 的大作中提到: 】
: 下面是一个test case,parse一个json file。必须提供json schema, 可以在
compile
: time的时候提示所有可能的类型结果和autocomplete。直接把整个json看成是一个
: object,然后查key是否存在的方案不考虑(不然我就直接用python了)
: https://stackoverflow.com/questions/59919496/how-to-parse-json-file-with-
: type-composition-of-stdoptional-and-stdvariant
: https://stackoverflow.com/questions/59903779/how-to-parse-json-with-field-of
: -optional-variant-in-haskell
: https://www.reddit.com/r/haskell/comments/etmgre/how_to_parse_json_with_
: field_of_optional_variant/
: 其实都是问同一个问题,parse 同一个json,链接里分别提供一个boiler plate可以直
: ...................

s
shuaide

not familiar with rapidjson.

Could you give an example about what you mean by those two modes?

【 在 pptwo (pp) 的大作中提到: 】
: 这种为啥不能用rapidjson的dom模式?我觉得sax模式都可以用。
: compile
: of

s
sanwadie

尝试一下java jackson轮子:定义一系列pojo,可以嵌套,用ObjectMapper 带
TypeReference 来解析。Pojo可以用一些注释来说明哪些值或嵌套对象是必须的,哪些可以省略,哪些json的属性名称和默认的java private变量需要特殊映射等。另外pojo里还可直接定义默认值。自己上网搜索一下相关内容,非常多。

p
pptwo

别自己造轮子,网上搜搜sax/dom这两种tree parser模式。
这玩意从XML的时代开始做起,到现在都有20年了。

【 在 shuaide (卖火柴的小女孩) 的大作中提到: 】
: not familiar with rapidjson.
: Could you give an example about what you mean by those two modes?

p
pptwo

对,没注意他用java也行,用jackson方便太多。

【 在 sanwadie (三娃爹) 的大作中提到: 】
: 尝试一下java jackson轮子:定义一系列pojo,可以嵌套,用ObjectMapper 带
: TypeReference 来解析。Pojo可以用一些注释来说明哪些值或嵌套对象是必须的,哪些
: 可以省略,哪些json的属性名称和默认的java private变量需要特殊映射等。另外
pojo
: 里还可直接定义默认值。自己上网搜索一下相关内容,非常多。

s
shuaide

我办公室里其他项目以前用jackson的,有些被我改写成用gson。因为jackson里面用到了log4j某些dependencies,把项目改成用multi module的parent pom来统一版本号的
时候很容易有conflict。就算用maven helper来exclude ,https://plugins.
jetbrains.com/plugin/7179-maven-helper, 发现都太烦了。逐个来exclude看不过来,索性不用jackson。

还有另外一个原因是jackson很多人用,却不是大牌子公司维护的东西,很多静态分析
的软件比如sonarQube和fortify都投诉要求升级到最新版。我实在说不过security部门的人,又不想经常升级,索性不用。换成gson,google的东西,他们找茬要也不到
google家东西的头上

s
shuaide

尝试了转成scala和java的class,把这里免费的方法全部试了一遍,都处理不了我那个list of json,只能手动。

因为要处理 optional的field,还有variant的比如同时可以是bool和string,比如你
看里面那个accuracy的类型。你可以用链接里面的随便一个试试:
https://www.google.com/search?q=json+to+pojo

【 在 pptwo (pp) 的大作中提到: 】
: 对,没注意他用java也行,用jackson方便太多。
: pojo

s
sanwadie

Optional field Jackson 肯定可以按标准方式处理;动态类型处理有两个方法:1)把field定义为Object;2)使用custom deserializer

【 在 shuaide (卖火柴的小女孩) 的大作中提到: 】
: 尝试了转成scala和java的class,把这里免费的方法全部试了一遍,都处理不了我那个
: list of json,只能手动。
: 因为要处理 optional的field,还有variant的比如同时可以是bool和string,比如你
: 看里面那个accuracy的类型。你可以用链接里面的随便一个试试:
: https://www.google.com/search?q=json+to+pojo

s
shuaide

(1)

dont consider any dynamic type approach like using Object. In this way, you need to is `instanceOf()` to determine the type at runtime, right? I dont
feel like Jackson can support Optional type in jdk8

(2)
What do you mean?

【 在 sanwadie (三娃爹) 的大作中提到: 】
: Optional field Jackson 肯定可以按标准方式处理;动态类型处理有两个方法:1)把
: field定义为Object;2)使用custom deserializer

p
pptwo

You can first use Jackson to load json as Maps/Lists of Maps/Lists, and
then write your own code to convert that into your own data types via
recursion.

You'll need to use Object to deal with variants anyway but you just need
to do it once during the conversion. I can see the need to use backtracking
if you cannot decide the actual type of the variant immediately.

Overall, since the json is already loaded as Maps of Maps, I don't think
this is more complicated than a recursive descent parser with backtracking.

【 在 shuaide (卖火柴的小女孩) 的大作中提到: 】
: (1)
: dont consider any dynamic type approach like using Object. In this way,
you
: need to is `instanceOf()` to determine the type at runtime, right? I dont : feel like Jackson can support Optional type in jdk8
: (2)
: What do you mean?

p
pptwo

BTW, there is no need to use Java 8 Optional to get optional semantics.

Java has optional semantics from day one - you can always use null.

【 在 shuaide (卖火柴的小女孩) 的大作中提到: 】
: (1)
: dont consider any dynamic type approach like using Object. In this way,
you
: need to is `instanceOf()` to determine the type at runtime, right? I dont : feel like Jackson can support Optional type in jdk8
: (2)
: What do you mean?

s
shuaide

took a look of the rapidjson. doesnt look good enough to support it.
【 在 pptwo (pp) 的大作中提到: 】
: 这种为啥不能用rapidjson的dom模式?我觉得sax模式都可以用。
: compile
: of

s
shuaide

took a look of the rapidjson. doesnt look good enough to support it.
【 在 pptwo (pp) 的大作中提到: 】
: 这种为啥不能用rapidjson的dom模式?我觉得sax模式都可以用。
: compile
: of