YamlDotNet icon indicating copy to clipboard operation
YamlDotNet copied to clipboard

YamlStream loses tag information

Open aaubry opened this issue 6 years ago • 7 comments

As reported here, YamlStream seems to be loosing tag information associated with mappings.

A preliminary investigation indicates that this is related to the IsCanonical property of MappingStart.

aaubry avatar Jun 04 '19 23:06 aaubry

The workaround in (https://dotnetfiddle.net/6Wz73c) seems to work, but with some tweaking.

In YamlDotNetCore the save method overload that accepts the emitter is not there, so I needed to use reflection as a workaround.

                var emitter = new MappingFix(new Emitter(writer));
                emitter.Emit((ParsingEvent)new StreamStart());
                foreach (YamlDocument doc in YamlStream.Documents)
                {
                    // The save method is not public in this version, so we'll have to call it internally. fugly? yes.. 
                    var invoker =
                        typeof(YamlDocument).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic);

                    invoker.Invoke(doc, new object[]{emitter, false});
                }
                emitter.Emit((ParsingEvent)new StreamEnd());

Erwinvandervalk avatar Jun 07 '19 10:06 Erwinvandervalk

I recommend that you update to the latest release of YamlDotNet instead. The YamlDotNet.NetCore package is maintained by someone else and there haven't been any updates to it since 2016.

aaubry avatar Jun 07 '19 11:06 aaubry

Ah.. you're right.. that works much better.. Thanks :)

Erwinvandervalk avatar Jun 07 '19 11:06 Erwinvandervalk

Tested this example against multiple implementations and it turned out that:

  • YDN, RubyYaml and libyaml etc. are generating identical event stream (parser and scanner part).
  • JavaScript YAML implementation errors out at !Cat.
  • cpp-yaml does not throw but misses the document end indicator (not a huge deal but pedantically behind).

So YDN's parser and scanner are pretty close to standard conformance for YAML 1.2 spec (5.11% spec tests pending conformance).

For the emitter, YamlStream/Serializer, would it make sense to make their default behavior conform with the output that official spec suite expect as well? I tested it to certain extent and out of 199 spec tests (that has out.yml), 191 fail for YamlStream and 150 fail for Serializer. Most of the differences are about missing document start indicator and floating point to be rounded to two decimal places precisely. If there are no APIs to adjust these (I could not find), we can add APIs such as to adjust fp precision .WithPrecision(int value = 2), for document start .WithoutDocumentIndicators() and so on. It will be a breaking change for existing consumers (who expect no-rounding of number and no document start marker), so perhaps it could target YDN v7.

am11 avatar Jun 08 '19 15:06 am11

I recommend that you update to the latest release of YamlDotNet instead. The YamlDotNet.NetCore package is maintained by someone else and there haven't been any updates to it since 2016.

The manager lists "Antoine Aubry" as author for both packages - shouldn't it be the same maintainer? Could we/someone/you remove the package?

Countryen avatar Apr 09 '22 11:04 Countryen

If you check on nugget.org you'll see that the package is published by someone else. I already contacted that person in the past and they said that they would unpublish the package. However they didn't. Feel free to contact them, maybe you will have more luck.

aaubry avatar Apr 09 '22 15:04 aaubry

the bug still persists.

var address = new YamlDocument(
    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")
  )
{  Tag = "Nomb"})
 ;
YamlStream st = new YamlStream(address);
using (TextWriter writer = File.CreateText("C:\\...\\some-file.yaml"))
{
    st.Save(writer, false);
}

with <PackageReference Include="YamlDotNet" Version="13.1.0" /> and the output is

street: |-
  123 Tornado Alley
  Suite 16
city: East Westville
state: KS
...

the tag just gets eaten

IXLLEGACYIXL avatar Jun 05 '23 12:06 IXLLEGACYIXL