Build a Yaml document dynamically from c#

后端 未结 2 1637
挽巷
挽巷 2020-12-20 16:16

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

相关标签:
2条回答
  • 2020-12-20 16:35

    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
                }
            )
        )
    );
    
    0 讨论(0)
  • 2020-12-20 16:37

    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.

    0 讨论(0)
提交回复
热议问题