使用 YAML.mapping 解析复杂的 YAML 结构
Parse complex YAML-structure with YAML.mapping
我在 YAML 中有这样复杂的结构
yaml = <<-STR
'Tunisie Telecom':
regex: 'StarTrail TT[);/ ]'
device: 'smartphone'
model: 'StarTrail'
Palm:
regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo|Xiino'
device: 'smartphone'
models:
- regex: '((?:Pre|Pixi))/(\d+\.\d+)'
model: ' '
- regex: 'Palm(?:[ \-])?((?!OS|Source|scape)[a-z0-9]+)'
model: ''
STR
我尝试用 YAML.mapping:
解析它
class Mobile
YAML.mapping(
name: Hash(String, Hash(String, String))
)
end
puts Mobile.from_yaml(yaml)
并得到解析异常:
Missing yaml attribute: name at line 1, column 1 (YAML::ParseException)
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/yaml/nodes/nodes.cr:30:9 in 'raise'
from mobiles_mapping.cr:0:3 in 'initialize'
from mobiles_mapping.cr:20:3 in 'new'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/yaml/from_yaml.cr:2:3 in 'from_yaml'
from mobiles_mapping.cr:25:1 in '__crystal_main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:11:3 in '_crystal_main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:112:5 in 'main_user_code'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:101:7 in 'main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:135:3 in 'main'
但是如果我尝试使用 YAML.parse 进行解析:
{"Tunisie Telecom" => {"regex" => "StarTrail TT[);/ ]", "device" => "smartphone", "model" => "StarTrail"}, "Palm" => {"regex" => "(?:Pre|Pixi)/(d+).(d+)|Palm|Treo|Xiino", "device" => "smartphone", "models" => [{"regex" => "((?:Pre|Pixi))/(d+.d+)", "model" => " "}, {"regex" => "Palm(?:[ -])?((?!OS|Source|scape)[a-z0-9]+)", "model" => ""}]}}
我的错误是什么?
在线示例:https://play.crystal-lang.org/#/r/41yk
UPD: 我明白了:宏找不到键 'name' 但是没有键如何解析 => val 就像在我只有键的情况下一样?
你有一个 Hash(String, Mobile)
,其中 Mobile
类似于
class Mobile
YAML.mapping({
regex: String,
device: String,
model: String?,
models: Array(...)?
})
end
所以,要解析你应该调用 Hash(String, Mobile).from_yaml
.
如果你的 YAML 是:
name:
'Tunisie Telecom':
regex: 'StarTrail TT[);/ ]'
device: 'smartphone'
model: 'StarTrail'
Palm:
regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo|Xiino'
device: 'smartphone'
models:
- regex: '((?:Pre|Pixi))/(\d+\.\d+)'
model: ' '
- regex: 'Palm(?:[ \-])?((?!OS|Source|scape)[a-z0-9]+)'
model: ''
我在 YAML 中有这样复杂的结构
yaml = <<-STR
'Tunisie Telecom':
regex: 'StarTrail TT[);/ ]'
device: 'smartphone'
model: 'StarTrail'
Palm:
regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo|Xiino'
device: 'smartphone'
models:
- regex: '((?:Pre|Pixi))/(\d+\.\d+)'
model: ' '
- regex: 'Palm(?:[ \-])?((?!OS|Source|scape)[a-z0-9]+)'
model: ''
STR
我尝试用 YAML.mapping:
解析它class Mobile
YAML.mapping(
name: Hash(String, Hash(String, String))
)
end
puts Mobile.from_yaml(yaml)
并得到解析异常:
Missing yaml attribute: name at line 1, column 1 (YAML::ParseException)
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/yaml/nodes/nodes.cr:30:9 in 'raise'
from mobiles_mapping.cr:0:3 in 'initialize'
from mobiles_mapping.cr:20:3 in 'new'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/yaml/from_yaml.cr:2:3 in 'from_yaml'
from mobiles_mapping.cr:25:1 in '__crystal_main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:11:3 in '_crystal_main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:112:5 in 'main_user_code'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:101:7 in 'main'
from /usr/local/Cellar/crystal-lang/0.24.2_1/src/crystal/main.cr:135:3 in 'main'
但是如果我尝试使用 YAML.parse 进行解析:
{"Tunisie Telecom" => {"regex" => "StarTrail TT[);/ ]", "device" => "smartphone", "model" => "StarTrail"}, "Palm" => {"regex" => "(?:Pre|Pixi)/(d+).(d+)|Palm|Treo|Xiino", "device" => "smartphone", "models" => [{"regex" => "((?:Pre|Pixi))/(d+.d+)", "model" => " "}, {"regex" => "Palm(?:[ -])?((?!OS|Source|scape)[a-z0-9]+)", "model" => ""}]}}
我的错误是什么?
在线示例:https://play.crystal-lang.org/#/r/41yk
UPD: 我明白了:宏找不到键 'name' 但是没有键如何解析 => val 就像在我只有键的情况下一样?
你有一个 Hash(String, Mobile)
,其中 Mobile
类似于
class Mobile
YAML.mapping({
regex: String,
device: String,
model: String?,
models: Array(...)?
})
end
所以,要解析你应该调用 Hash(String, Mobile).from_yaml
.
如果你的 YAML 是:
name:
'Tunisie Telecom':
regex: 'StarTrail TT[);/ ]'
device: 'smartphone'
model: 'StarTrail'
Palm:
regex: '(?:Pre|Pixi)/(\d+)\.(\d+)|Palm|Treo|Xiino'
device: 'smartphone'
models:
- regex: '((?:Pre|Pixi))/(\d+\.\d+)'
model: ' '
- regex: 'Palm(?:[ \-])?((?!OS|Source|scape)[a-z0-9]+)'
model: ''