我正在尝试做我认为在YAML中简单的事情。这是具有重复元素的简单层次结构。下面的第一个示例非常接近,但是每个 node 序列元素都会触发错误:“序列条目缩进不良”。我看不出有什么问题。
请注意,我在下面提供了一个可行的示例,但是它使用的唯一键不是我想要的。
- agegrp: 1
- node : "(14, 6)"
# id: "(14, 6)"
- branch : "to 7"
id : "to 7"
tocond : 7
pr : 1.0
next : (0, 0)
- node : "(14, 7)"
# id: "(14,7)"
- branch : "to 7"
id : "to 7"
tocond : 7
pr : 0.85
next : (0, 0)
- branch : "to 8"
id : "to 8"
tocond : 8
pr : 0.15
next : (4, 4)
- agegrp : 2
- node : "(14, 6)"
# id: "(14, 6)"
- branch : "to 7"
id : "to 7"
tocond : 7
pr : 1.0
next : (0, 0)
- node : "(14, 7)"
# id: "(14,7)"
- branch : "to 7"
id : "to 7"
tocond : 7
pr : 0.85
next : (0, 0)
- branch : "to 8"
id : "to 8"
tocond : 8
pr : 0.15
next : (4, 4)
请注意以下内容有效,但是我不希望分支和节点具有唯一的名称。我想要一个重复的结构。我可以在分支和节点的前面使用破折号,但这会导致另一个问题:序列条目的缩进错误。
agegrp:
id: 1
node (14, 6):
# id: "(14, 6)"
branch:
id: "to 7"
tocond: 7
pr: 1.0
next: (0, 0)
node (14,7):
# id: "(14,7)"
branch to 7:
id: "to 7"
tocond: 7
pr: 0.85
next: (0, 0)
branch to 8:
id: "to 8"
tocond: 8
pr: 0.15
next: (4, 4)
将有5个年龄段。节点在年龄组内。分支在节点内。每个分支都有3个属性。我可以在每个节点下放置一个id项目,而不是上面显示的那样。
我对于何时必须使用前导破折号感到困惑,何时不可以使用。我对何时允许值以及何时不允许值感到困惑。
在YAML中甚至有可能吗? TOML不喜欢层次结构。到目前为止,我已经将其保存在csv中并进行了解析,并在代码中构建了一个字典。我以为我可以使用本来可以代表层次结构的格式。
我想要的输出:
这里是一个例子:这是一个针对年龄段的字典:
(1, 1) =>
CovidSim.Branch(5, 5, 0.2, (2, 1), "nil", "nil")
CovidSim.Branch(5, 6, 0.65, (2, 2), "nil", "mild")
CovidSim.Branch(5, 7, 0.15, (2, 3), "nil", "sick")
(2, 1) =>
CovidSim.Branch(5, 3, 0.8, (0, 0), "nil", "recovered")
CovidSim.Branch(5, 7, 0.2, (3, 3), "nil", "sick")
(2, 2) =>
CovidSim.Branch(6, 6, 1.0, (3, 2), "mild", "mild")
(2, 3) =>
CovidSim.Branch(7, 7, 0.85, (3, 3), "sick", "sick")
CovidSim.Branch(7, 8, 0.15, (3, 4), "sick", "severe")
(3, 2) =>
CovidSim.Branch(6, 3, 1.0, (0, 0), "mild", "recovered")
(3, 3) =>
CovidSim.Branch(7, 3, 0.8, (0, 0), "sick", "recovered")
CovidSim.Branch(7, 7, 0.1, (5, 3), "sick", "sick")
CovidSim.Branch(7, 8, 0.1, (4, 4), "sick", "severe")
(3, 4) =>
CovidSim.Branch(8, 3, 0.45, (0, 0), "severe", "recovered")
CovidSim.Branch(8, 8, 0.5, (4, 4), "severe", "severe")
CovidSim.Branch(8, 4, 0.05, (0, 5), "severe", "dead")
(4, 4) =>
CovidSim.Branch(8, 3, 0.85, (0, 0), "severe", "recovered")
CovidSim.Branch(8, 8, 0.1, (5, 4), "severe", "severe")
CovidSim.Branch(8, 4, 0.05, (0, 5), "severe", "dead")
(5, 3) =>
CovidSim.Branch(7, 3, 0.9, (0, 0), "sick", "recovered")
CovidSim.Branch(7, 4, 0.1, (0, 5), "sick", "dead")
(5, 4) =>
CovidSim.Branch(8, 3, 0.6, (0, 0), "severe", "recovered")
CovidSim.Branch(8, 4, 0.4, (0, 5), "severe", "dead")
外部容器是5个年龄段字典的数组。
(请注意,此示例在我要减少的每个分支中都包含一些额外的字段。)
谢谢!
答案 0 :(得分:2)
如果您查看YAML spec的收藏夹
YAML的阻止集合使用缩进范围,并开始每个 单独输入。
块顺序用破折号表示每个条目 和空格(“-”)。
映射使用冒号和空格(“:”)标记每个 键:值对。
注释以八齿形(也称为a “哈希”,“清晰”,“磅”或“数字符号”-“#”)。
所以你
- agegrp: 1
是序列和图谱的融合
您可以这样做
---
-
id: 1
nodes:
-
branches:
-
id: "to 7"
next: "(0, 0)"
pr: 1.0
tocond: 7
-
id: "to 7"
next: "(0, 0)"
pr: 0.85
tocond: 7
-
id: "to 8"
next: "(4, 4)"
pr: 0.15
tocond: 8
id: "(14, 6)"
如果这符合您的需求
答案 1 :(得分:1)
按照您自己的答案进行操作:YAML 确实允许您将实体名称放入YAML文件中。通过为标签提供语法来实现。这是一个文件外观示例:
!agegrp 4:
!node [9,6]:
- !branch
tocond: 6
next:
- 14
- 6
pr: 1.0
!node [9,5]:
- !branch
tocond: 3
next:
- 0
- 0
pr: 0.8
- !branch
tocond: 7
next:
- 14
- 7
pr: 0.2
请注意,我将YAML序列用于节点坐标,因为看起来您还是想将它们解析为数字对((9,6)
会解析为字符串)。您可以保留原始语法。
这是将标记后的值直接与其关联。因此,4
将被标记为!agegrp
,序列[9,6]
将被标记为!node
,而包含tocond
等的映射将被标记为!branch
。这些本地标记是应用程序定义的;您将需要使用大多数YAML实现为它们注册处理程序。
从语义上讲,这会将4
标记为 agegrp (无论是什么),而节点不属于该 agegrp 对象的一部分–使用此标记,只有键4
被标记为 agegrp 。当然,如何处理文件取决于您。一种替代方法是:
4: !agegrp
!node [9,6]:
…
现在,包含节点的映射标记为 agegrp ,而4
只是映射中的键(可能解析为整数)。
如果您希望ID成为对象的一部分,则可以将文档转换为基于序列的结构, @KeepCalmAndCarryOn 已经显示了执行此操作的常用方法,以下是使用标签的一种方法:
- !agegrp
- !id 4
- !node
- !id [9,6]
- !branch
tocond: 6
next:
- 14
- 6
pr: 1.0
- !node
- !id [9,5]
- !branch
tocond: 3
next:
- 0
- 0
pr: 0.8
- !branch
tocond: 7
next:
- 14
- 7
pr: 0.2
这是为了平整 node 的内部结构,以便ID和分支可以处于同一级别。这要求加载代码在加载该YAML时正确区分!id
和!branch
节点。这种结构经常用在XML中,它不提供像YAML那样的映射,因此,所有嵌套结构都是序列,并且不同的子代通过其元素名称来区分。
答案 2 :(得分:0)
感谢您的帮助。我并没有绕过YAML并创建没有任何名称的实体组。 @KeepCalmAndCarryOn:您的结构导致在同一级别上具有id项和branch项的节点数组(branch项是分支的数组,每个分支都是属性的字典。这有效,但不显示非常好并且更难使用(但肯定包含示例中的所有信息)。
我更喜欢严格的等级制度。我手动编码json。然后,将json解析为嵌套的julia对象:这样的字典数组:
async function fetchMessages() {
$.ajax({
type: "POST",
url: "../ASPX/bubblelandFetch.aspx",
success: function (data) {
console.log(data);
data = JSON.parse(data);
var container = document.getElementById("messages-container");
var uid;
container.innerHTML = "";
console.log(data);
for (var i in data) {
var message = '<div id="' + data[i]["mid"];
message += '" class="message ' + data[i]["color"] + '">';
message += '<div class="profile-container">';
if (data[i]["uid"] == "user")
uid = "/Media/user"
else
uid = "/Media/Profile/" + data[i]["uid"];
message += '<img src="' + uid + '.png"/>';
message += '<span>' + data[i]["name"] + '</span></div>';
message += '<div class="content">' + data[i]["content"] + '</div>';
container.innerHTML += message;
}
},
complete: function () {
setTimeout(fetchMessages, intevral);
}
});
}
输出被截断,但是您可以将每个年龄组视为一个键-以节点的格为其值。节点的每个字典显示第一个键(一个节点),并以分支数组作为其值。分支数组中的每个项目都是分支的每个属性的字段的决定。
一个agegrp看起来像这样:
Dict{String,Any} with 5 entries:
"4" => Dict{String,Any}("(9,6)"=>Any[Dict{String,Any}("tocond"=>6,"next"=>Any…
"1" => Dict{String,Any}("(9,6)"=>Any[Dict{String,Any}("tocond"=>6,"next"=>Any…
"5" => Dict{String,Any}("(9,6)"=>Any[Dict{String,Any}("tocond"=>6,"next"=>Any…
"2" => Dict{String,Any}("(9,6)"=>Any[Dict{String,Any}("tocond"=>6,"next"=>Any…
"3" => Dict{String,Any}("(9,6)"=>Any[Dict{String,Any}("tocond"=>6,"next"=>Any…
然后,我将这个Julia嵌套对象(有点陈旧,但结构更清晰-至少对我来说),并通过YAML将其放置以创建有效的YAML输出。
这个YAML正是我真正想要的,即使对于正确使用YAML的人来说这似乎令人讨厌。这只是一个agegrp(其他结构相同,并且在YAML文档中依次执行):
Dict{String,Any} with 8 entries:
"(9,6)" => Any[Dict{String,Any}("tocond"=>6,"next"=>Any[14, 6],"pr"=>1.0)]
"(9,5)" => Any[Dict{String,Any}("tocond"=>3,"next"=>Any[0, 0],"pr"=>0.8), Di…
"(14,6)" => Any[Dict{String,Any}("tocond"=>3,"next"=>Any[0, 0],"pr"=>1.0)]
"(9,7)" => Any[Dict{String,Any}("tocond"=>7,"next"=>Any[14, 7],"pr"=>0.85), …
"(5,5)" => Any[Dict{String,Any}("tocond"=>5,"next"=>Any[9, 5],"pr"=>0.2), Di…
"(14,8)" => Any[Dict{String,Any}("tocond"=>3,"next"=>Any[0, 0],"pr"=>0.45), D…
"(14,7)" => Any[Dict{String,Any}("tocond"=>3,"next"=>Any[0, 0],"pr"=>0.85), D…
"(19,8)" => Any[Dict{String,Any}("tocond"=>3,"next"=>Any[0, 0],"pr"=>0.9), Di…
这遵循我想要的层次结构:
4: # the id of an agegrp
(9,6): # the id of a node
- tocond: 6 # first property of a branch
next:
- 14
- 6
pr: 1.0
(9,5):
- tocond: 3
next:
- 0
- 0
pr: 0.8
- tocond: 7
next:
- 14
- 7
pr: 0.2
(14,6):
- tocond: 3
next:
- 0
- 0
pr: 1.0
(9,7):
- tocond: 7
next:
- 14
- 7
pr: 0.85
- tocond: 8
next:
- 14
- 8
pr: 0.15
<rest of output truncated...>
我确实通过将实体名称(agegrp,节点,分支)与每个实体的特定实例的实际值混合在一起弄乱了自己—就像我试图用类型标记每个事物。您不会在字典中那样做。我在这里使用Julia,但Dicts本质上与Python中相同。
因此,对YAML的尝试有点令人沮丧。但是,它比我刚开始使用的CSV输入要容易得多,比手工编写JSON要容易得多。因此,成功的尝试!