Build a Yaml document dynamically from c#

笑着哭i 提交于 2019-12-23 09:06:18

问题


Is it possible to build a Yaml document dynamically from c# with Yaml.DotNet or another library?

I understand how this can be done using serialisation, however that requires starting with an object structure.

I'm looking to find a way to create the Yaml document nodes on the fly as you would with Xml using the XElement.Add(object) method for example.


回答1:


You can do that using YamlDotNet. You start by creating a YamlStream, add one or more document to it, then you can add sequences, mappings and scalars to it.

Here is an example on how to do it:

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
            }
        )
    )
);



回答2:


I've now worked out how to do this using Yaml.Net. The YamlStream needs to be loaded with some initial content using the Load() method.

const string initialContent = "---\nversion: 1\n...";

var sr = new StringReader(initialContent);
var stream = new YamlStream();
stream.Load(sr);

You can then cast the RootNode of the YamlDocument to YamlMappingNode which has an Add method.

var rootMappingNode = (YamlMappingNode)stream.Documents[0].RootNode;   
rootMappingNode.Add("shout", "yay!");

You can then add a variety of node types before saving:

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);

The output from this example is:

version: 1
shout: yay!
itemWithProps:
  prop1: value1
  prop2: value2
sequenceOfItems:
- prop1: value1
  prop2: value2
- prop1: value1
  prop2: value2
- collection: [a, b, c]
...

Thanks to @Antoine Aubry for creating Yaml.Net and vaguely pointing me in right direction.



来源:https://stackoverflow.com/questions/37116684/build-a-yaml-document-dynamically-from-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!