aaubry / YamlDotNet

YamlDotNet is a .NET library for YAML
MIT License
2.58k stars 486 forks source link

Load yaml file with duplicated keys #764

Open yz7788 opened 1 year ago

yz7788 commented 1 year ago

Is there a way to load yaml files with duplicated keys without throwing any exception?

EdwardCooke commented 1 year ago

Can you provide a minimal example of code and yaml that throws the error? There was a pr that we merged in a little bit ago that would throw on duplicate keys, but that was an opt in feature where you had to explicitly enable it.

yz7788 commented 1 year ago

Thanks for your reply! I met this problem when trying to load a Asset Prefab Yaml from a Unity project. It seems that Unity allows duplicated keys while Yaml standard syntax actually do not.

I shorten the prefab yaml and attached it as a file. duplicatedkeyexample.txt

Here is the code I use: string yamlStr = Regex.Replace(System.IO.File.ReadAllText(filePath), "([0-9]+ &[0-9]+) stripped\n", "$1\n"); var yaml = new YamlStream(); var reader = new StringReader(yamlStr); yaml.Load(reader);

An Exception will be thrown when yaml.Load():

YamlDotNet.Core.YamlException:“(Line: 39, Col: 3, Idx: 1183) - (Line: 39, Col: 12, Idx: 1192): Duplicate key” ArgumentException: An item with the same key has already been added. Key: enableLOD

EdwardCooke commented 1 year ago

Thanks for the example. I’ll take a look at it when I get some time. Might be a couple of days.

yz7788 commented 1 year ago

Thanks!

EdwardCooke commented 1 year ago

Is this still a problem for you with the latest version?

afilatov-st commented 1 year ago

@EdwardCooke the YamlStreamstill does not allow to load YAMLs with duplicate keys in the "mapping" node. YamlMappingNode uses OrderedDictionary internally which is based on regular dictionary and when children.Add() is called, the exception is thrown because the dictionary already contains the key. I understand that the Yaml standard prohibits non-unique keys, but some systems still consider YAML files with duplicates valid (for instance Kubernetes ConfigMaps). It would be great if this library allows to load them somehow, for example, via a configuration option or via a delegate that is called for duplicates.

EdwardCooke commented 1 year ago

Ok, I'll take a look when I get time. Work is brutal right now, so it may be a week or 2. I didn't think the yamlstream used a dictionary at all, thought it just dumped out the individual yamlnodes. I'll let you know what I find.

safayilmaz56 commented 11 months ago

Hello I also encountered the same problem, was there any solution found

EdwardCooke commented 11 months ago

Can you post in a small snippet of code and yaml to reproduce the problem?

EdwardCooke commented 11 months ago

Never mind. Just found it. I just need some more time to think about how to solve this without making a big impact. My initial idea is to add another property/argument on the YamlDtream class or Load method that allows duplicates. With that in place I can use a list in the YamlMappingNode instead of a dictionary, and if duplicate keys is not enabled, keep track of them and throw on duplicates if not enabled. The Children property would remain a dictionary but it would convert the list to that dictionary. I think it would work. I’ll see if I can find some time in the next day or 2. Pr’s are also welcome if you need it sooner.

safayilmaz56 commented 10 months ago

Thank you for response. I hope this answer will solve the problem

EdwardCooke commented 4 months ago

I’ll be working on this and getting a fix out shortly.

492720891 commented 4 weeks ago

Hi, I found that the latest version 16.1.13 still throw exception if there is a duplicate key, can ignore the later duplicate key and don't throw exception? Or add a switch to indicate how to handle duplicate key? Throw exception or ignore the later one?