-
-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I cannot figure out how to parse a YAML file with a key like "[0 cm, 1 cm]:" that can change #471
Comments
Without further details, it is not clear what would be the correct model to represent your data. One possible approach would be to define a custom type to represent // This assumes that exactly two lengths will be specified in a list.
// An alternative would be to just use a List<Length>
class Range
{
public Length Start { get; set; }
public Length End { get; set; }
}
class Length
{
public int Value { get; set; }
public string Units { get; set; }
} By default YamlDotNet would represent each of these classes as mappings, so we will need to change that behaviour. One way is to implement Let's start with the class Length : IYamlConvertible
{
public int Value { get; set; }
public string Units { get; set; }
void IYamlConvertible.Read(IParser parser, Type expectedType,
ObjectDeserializer nestedObjectDeserializer)
{
var scalar = parser.Consume<Scalar>();
var parts = scalar.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries);
this.Value = int.Parse(parts[0]);
this.Units = parts[1];
}
void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
{
emitter.Emit(new Scalar($"{Value} {Units}"));
}
} Then the class Range : IYamlConvertible
{
public Length Start { get; set; }
public Length End { get; set; }
void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
{
parser.Consume<SequenceStart>();
this.Start = (Length)nestedObjectDeserializer(typeof(Length));
this.End = (Length)nestedObjectDeserializer(typeof(Length));
parser.Consume<SequenceEnd>();
}
void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
{
emitter.Emit(new SequenceStart(null, null, false, SequenceStyle.Flow));
nestedObjectSerializer(this.Start);
nestedObjectSerializer(this.End);
emitter.Emit(new SequenceEnd());
}
} With the above types defined, we are able to parse the YAML as follows: class Model
{
public Dictionary<Range, object> HeightSensor { get; set; }
}
public static void Main()
{
var yaml = @"
HeightSensor:
[0 cm, 1 cm]:
- - set
- HeightSensor
- frequency: 10 sec
";
var deserializer = new DeserializerBuilder()
.Build();
var model = deserializer.Deserialize<Model>(yaml);
} Since your question was focused on parsing the Here you can see the fully working code: |
First off, I really appreciate this. It works perfectly! I am parsing the entire YAML file, that is in the zip folder attached. The issue I am having now is when I Serialize the class, with new data, the output is not in the same form as the original file. I want to edit values and write the file to a .yml file without all the new '?' characters, extra values in the START and END keys, and the "String:" key after "- -". My classes with your implementation used in MONITOR: `public class ConfigFile
The output when I serialize is output.txt in zip |
There’s been no comments in over 4 years. Closing this. FYI, a custom type emitter could probably be used for this. |
I cannot figure out how to parse a YAML file with this structure:
HeightSensor:
[0 cm, 1 cm]:
- - set
- HeightSensor
- frequency: 10 sec
The "[0 cm, 1 cm]:" is super problematic. Can anyone help me with the C# struct/class I need to represent this so I can Deserialize the YAML file? Or if there is a better way?
These number values can change so how do I parse a key with a variable name like this?
The text was updated successfully, but these errors were encountered: