Reputation: 91618
I'm looking to implement an extension method similar to this:
public static bool RemoveNode(this YamlDocument doc, YamlNode node)
{
}
Basically, I have a YamlDocument
, and a YamlNode
I would like to remove from that document. Neither YamlDocument
or YamlNode
appear to have any sort of Remove
method. Judging by the source code, it looks like child nodes (at least for Mapping Nodes) are stored in the children
dictionary, which could be accessed through the Children
property. I would probably also need to solve this for removing sequence nodes and scalar nodes. If anyone has solved this issue, I'd love to hear your approach.
Also, I ran across another library called SharpYaml (which appears to be a fork of YamlDotNet) which has methods build in to remove nodes. However, at the moment it would be somewhat of a high cost to switch out Yaml libraries. So, that's a last resort.
Upvotes: 1
Views: 580
Reputation: 39708
The question is: What should be the semantics of removing the YamlNode? Simple example:
one:
two: three
four:
- five
- six
- seven
Assume I call some remove method on the nodes containing three
and six
. Would the result be:
one: {}
four:
- five
- seven
Or rather:
one:
two: !!null ~
four:
- five
- !!null ~
- seven
With the first option, you also remove the node two
from the document and change the index of seven
. With the second option, you replace the node with null nodes instead of removing them. Which is right? For two
: If you want to eventually load that YAML mapping into a class object which has a field two
, you probably want to keep the two
and just replace the value with null. If you want to load it into a dictionary however, you probably also want to remove the key two
. We see: The details of how removal should work depend on the semantics of your graph, and since YamlDotNet does not know anything about it, it can't decide that for you.
Here's another interesting case:
foo: &a
bar: *a
What should happen when you remove the inner mapping value with the &a
anchor? In a YamlDocument, this will be a YamlNode that will be referenced from two places. Could it be that you actually only want to remove the reference generated by the alias *a
? Or if you want to remove the outer reference, do you want the YamlNode object to still hold a reference to itself after the removal from the document?
Assuming you have answers to those questions, a graph traversal doesn't seem that hard to implement. Keep a HashSet
of visited nodes to break cycles, For each sequence and mapping descend into their children, and every time you find the YamlNode that should be removed, perform the appropriate action depending on how you answered the questions above.
Upvotes: 1