我正在使用Racket以及yaml和json库将某些Yaml文档转换为json。两者似乎都工作得很好,但不一定一起工作。冒着这个问题的风险(我对惯用的解决方案很感兴趣),有人可以指出我正确的方向吗?
示例yaml:
Title: Example
Description: An example
Content:
Type1:
- foo
- bar
- baz
Type2:
- chocolate
- vanilla
- strawberry
我快速转换Yaml:
#lang racket/base
(require json
yaml)
; reading is easy
(define example-yaml (file->yaml "./example.yaml"))
; writing doesn't like the keys-as-strings... why not?
; (write-json example-yaml)
; write-json: expected argument of type <legal JSON key value>; given: "Description"
; keys-as-symbols seems to be fine
(define example-yaml-2
#hash((Content
.
#hash((Type1 . ("foo" "bar" "baz"))
(Type2 . ("chocolate" "vanilla" "strawberry"))))
(Description . "An example")
(Title . "Example")))
(write-json example-yaml-2)
; {"Content":{"Type2":["chocolate","vanilla","strawberry"],"Type1":["foo","bar","baz"]},"Description":"An example","Title":"Example"}
我收集到的问题是json包没有将字符串视为jsexpr中的有效键。 The docs给出以下示例:
> (jsexpr? #hasheq(("turnip" . 82)))
#f
我坐在那里的选项似乎是:
(jsexpr? #hasheq(("turnip" . 82)))
视为#t
我想我并不完全理解这些选项的含义(或对实现有扎实的把握)。我也不是很确定为什么键字符串不是有效的jsexprs,因为它发出的json也使用字符串作为键。感谢您提供的任何见解!
对于方法3,仅将哈希表键从字符串更改为符号可能还不够。这取决于您对数据格式的了解程度。
例如,yaml
包允许各种各样的东西作为“键”,不仅是字符串,而且还可以是二进制数据,数字,哈希图或任何其他Yaml对象(键可以是任意节点)。
所以您必须:
现在,我假设(1),您已经事先知道所有键都是字符串。
;; yaml-key->symbol
;; In my Yaml data, I know beforehand that all keys are strings
(define (yaml-key->symbol key)
(cond
[(string? key) (string->symbol key)]
[else
(error 'yaml-key->symbol
"expected all Yaml keys to be strings, but got: ~v"
key)]))
[Yamml和Json之间可能还需要考虑其他潜在的不匹配。
对于每个问题,都要做出决定并记录下来。或者,如果您提前知道您的Yaml数据绝对不包含其中任何一个,则也要进行记录,并通过类似于以上yaml-key->symbol
的错误进行验证。
一旦您知道如何转换您可能会在数据中看到的所有内容,就可以递归地遍历Yaml并将其转换为Json。