Создайте документ Yaml динамически из C#
Можно ли динамически создать документ Yaml из C# с помощью Yaml.DotNet или другой библиотеки?
Я понимаю, как это можно сделать с помощью сериализации, однако для этого необходимо начать со структуры объекта.
Я ищу способ создания узлов документов Yaml на лету, как если бы вы использовали Xml, используя, например, метод XElement.Add(object).
2 ответа
Вы можете сделать это с помощью YamlDotNet. Вы начинаете с создания YamlStream, добавляете в него один или несколько документов, затем вы можете добавлять в него последовательности, отображения и скаляры.
Вот пример того, как это сделать:
var address = new YamlMappingNode(
new YamlScalarNode("street"),
new YamlScalarNode("123 Tornado Alley\nSuite 16") { Style = YamlDotNet.Core.ScalarStyle.Literal },
new YamlScalarNode("city"),
new YamlScalarNode("East Westville"),
new YamlScalarNode("state"),
new YamlScalarNode("KS")
) { Anchor = "main-address" };
var stream = new YamlStream(
new YamlDocument(
new YamlMappingNode(
new YamlScalarNode("repeipt"),
new YamlScalarNode("Oz-Ware Purchase Invoice"),
new YamlScalarNode("date"),
new YamlScalarNode("2007-08-06"),
new YamlScalarNode("customer"),
new YamlMappingNode(
new YamlScalarNode("given"),
new YamlScalarNode("Dorothy"),
new YamlScalarNode("family"),
new YamlScalarNode("Gale")
),
new YamlScalarNode("items"),
new YamlSequenceNode(
new YamlMappingNode(
new YamlScalarNode("part_no"),
new YamlScalarNode("A4786"),
new YamlScalarNode("descrip"),
new YamlScalarNode("Water Bucket (Filled)"),
new YamlScalarNode("price"),
new YamlScalarNode("1.47"),
new YamlScalarNode("quantity"),
new YamlScalarNode("4")
),
new YamlMappingNode(
new YamlScalarNode("part_no"),
new YamlScalarNode("E1628"),
new YamlScalarNode("descrip"),
new YamlScalarNode("High Heeled \"Ruby\" Slippers"),
new YamlScalarNode("price"),
new YamlScalarNode("100.27"),
new YamlScalarNode("quantity"),
new YamlScalarNode("1")
)
),
new YamlScalarNode("bill-to"), address,
new YamlScalarNode("ship-to"), address,
new YamlScalarNode("specialDelivery"),
new YamlScalarNode("Follow the Yellow Brick\n" +
"Road to the Emerald City.\n" +
"Pay no attention to the\n" +
"man behind the curtain.")
{
Style = YamlDotNet.Core.ScalarStyle.Literal
}
)
)
);
Сейчас я разобрался, как это сделать, используя Yaml.Net. YamlStream необходимо загрузить с некоторым начальным содержимым, используя метод Load().
const string initialContent = "---\nversion: 1\n...";
var sr = new StringReader(initialContent);
var stream = new YamlStream();
stream.Load(sr);
Затем вы можете привести RootNode YamlDocument к YamlMappingNode, который имеет метод Add.
var rootMappingNode = (YamlMappingNode)stream.Documents[0].RootNode;
rootMappingNode.Add("shout", "yay!");
Затем вы можете добавить различные типы узлов перед сохранением:
var props = new YamlMappingNode();
props.Add("prop1", "value1");
props.Add("prop2", "value2");
rootMappingNode.Add("itemWithProps", props);
var props2 = new YamlMappingNode();
props2.Add("prop1", "value1");
props2.Add("prop2", "value2");
var props3 = new YamlMappingNode();
props3.Add("prop1", "value1");
props3.Add("prop2", "value2");
var seq = new YamlSequenceNode();
seq.Add(props2);
seq.Add(props3);
rootMappingNode.Add("sequenceOfItems", seq);
var col = new YamlSequenceNode();
col.Style = SequenceStyle.Flow;
col.Add("a");
col.Add("b");
col.Add("c");
var seqMapping = new YamlMappingNode();
seqMapping.Add("collection", col);
seq.Add(seqMapping);
using (TextWriter writer = File.CreateText("C:\\temp\\test.yaml"))
stream.Save(writer, false);
Выход из этого примера:
version: 1
shout: yay!
itemWithProps:
prop1: value1
prop2: value2
sequenceOfItems:
- prop1: value1
prop2: value2
- prop1: value1
prop2: value2
- collection: [a, b, c]
...
Спасибо @Antoine Aubry за создание Yaml.Net и расплывчато указывающих мне в правильном направлении.