Closed GoogleCodeExporter closed 9 years ago
Issue 187 has been merged into this issue.
Original comment by jbe...@gmail.com
on 29 Jan 2013 at 2:22
This is sorta intentional. YAML doesn't specify the ordering of key/value pairs
in a map, so you're not supposed to rely on it.
However, I do see some value to it, so I will consider it. I'm just not
convinced yet :)
Original comment by jbe...@gmail.com
on 29 Jan 2013 at 2:23
The way I see it, yaml-cpp is a tool for parsing files. A file is a (ordered)
sequence of information. This is especially true with YAML as it is meant to be
streamable. Therefore a YAML parser should somehow keep this information.
Of course there is the issue of creating a non-standard behavior people might
start relying on, and the issue of implementation overhead to keep the ordering
while still allowing fast search for keys.
Your suggestion to turn it into a sequence of single-element maps is not a bad
one. I'll consider it.
Original comment by oster.t...@gmail.com
on 29 Jan 2013 at 7:04
I appreciate that it's a potentially useful thing to do; but yaml-cpp is a tool
to parse YAML, which does not specify the ordering of key/value pairs in a map.
(A related situation: yaml-cpp also does not preserve stray whitespace. It is
*not* a goal of the library to be able to write a file exactly as it read it.)
The fact that YAML is streamable is a red herring - the YAML spec *explicitly*
says that key order is an implementation detail
(http://www.yaml.org/spec/1.2/spec.html#id2765608).
Again, though, this is one of those things that I do see some value in, so I'll
think about it. One problem is that some people want to maintain order and
others want it to be ordered alphabetically, and I'm not a huge fan of
proliferation of configuration details.
Original comment by jbe...@gmail.com
on 29 Jan 2013 at 9:08
It would be great to have order preserved, especially in configuration files.
So one could provide some common options to be changed from UI and other leave
to edit manually in configuration file.
Original comment by perch...@gmail.com
on 24 Jan 2014 at 6:18
Currently you can:
1. Save whole doc using Node::Clone
2. During save, check Node::GetMark().line
Original comment by end...@gmail.com
on 24 Apr 2014 at 1:47
Maybe you could offer a non-standard extension of some sort? That would make it
clear that it's not part of the standard, yet allow you to provide useful
behavior for those who want it.
Original comment by jwbdec...@gmail.com
on 9 Jul 2014 at 7:45
> Currently you can:
> 1. Save whole doc using Node::Clone
> 2. During save, check Node::GetMark().line
Could you please explain this solution in detail?
Original comment by gim6...@gmail.com
on 19 Jul 2014 at 11:19
There's already a struct Mark that tells you a location in a file.
You can change
NodeBuilder::OnScalar/NodeBuilder::OnSequenceStart/NodeBuilder::OnMapStart by
uncommenting "mark" from the parameters and telling "node" to save the "mark".
To tell the node to save the mark, you will need to add a new member variable
"mark" to node_data and implement getters/setters up the chain (node_ref,
detail::node, Node).
If you want Clone() to work, you will also need to change NodeEvents::Emit to
pass in the actual mark instead of constructing an empty mark.
Original comment by henear...@gmail.com
on 23 Jul 2014 at 5:19
Does anyone know how it reorders the nodes? I can't seem to figure out a
pattern.
Original comment by justin.j...@gmail.com
on 19 Feb 2015 at 9:47
For save nodes in determining order I use Yaml::Emitter. For example:
void Author::customToYaml(YAML::Emitter &out) const
{
out << YAML::Key << "companyName" << YAML::Value << companyName();
out << YAML::Key << "companySite" << YAML::Value << companySite();
}
Original comment by gil.il...@gmail.com
on 19 Feb 2015 at 9:55
@justin, #10: it's arbitrary-ish, based on pointer keys.
Original comment by jbe...@gmail.com
on 19 Feb 2015 at 3:38
I also would like more ordered output. I fully get that YAML is using unordered
maps, but it's very weird when hand-editting YAML files, and each object is in
a different order.
Example:
YAML::Node root;
for(const auto &pair : this->Details.MaterialDetails)
{
Engine::MaterialID materialID = pair.first;
const Engine::MaterialDetails &materialDetails = pair.second;
YAML::Node material;
material["MaterialID"] = materialID;
material["DisplayName"] = materialDetails.displayName;
material["SoundID"] = materialDetails.soundID;
root["Materials"].push_back(material);
}
I find it really odd that iterating over elements in my map, each element of
the map will have its members outputted arbitrarily from one another.
Materials:
- DisplayName: Fallthrough
SoundID: 0
MaterialID: 2
- SoundID: 0
DisplayName: Default
MaterialID: 1
- MaterialID: 0
DisplayName: None
SoundID: 0
Each element is in a different order. I don't expect the elements in any
particular order, but a consistent order would be nice. Maybe you can output
mapped values by alphabetical (or numerical) order of the key, or some other
arbitrary-but-consistent order?
Original comment by JaminThe...@gmail.com
on 26 Feb 2015 at 9:35
It's on the table to output a consistent ordering. It's not on the table to
iterate in a consistent ordering.
Original comment by jbe...@gmail.com
on 26 Feb 2015 at 9:49
Yes, consistent output is what I'm asking for, not consistent iteration. The
iteration of 'MaterialDetails' in my example above is an std::unordered_map not
yaml-cpp, sorry for the confusion.
I was trying to demonstrate that outputting while in any kind of loop still
produces unordered (but correct) output, despite using the exact same functions
in the exact same order. Which you're aware of.
Original comment by JaminThe...@gmail.com
on 27 Feb 2015 at 6:38
Hmm, so I tried using the emitter to emit the key and value one by one to get
the correct order. My code looks like this:
for (YAML::const_iterator it = baseNode.begin(); it != baseNode.end(); ++it) {
YAML::Node key = it->first;
YAML::Node value = it->second;
if (value.IsScalar()) {
emitter << YAML::Key << key.as< std::string >() << YAML::Value
<< value.as< std::string >();
} else {
// Otherwise a map
emitter << YAML::Key << key.as< std::string >();
emitter << YAML::Value << YAML::BeginMap;
SaveBaseNode(value, emitter);
emitter << YAML::EndMap;
}
}
The output is still not ordered. I'm guessing there is no solution to this...?
Original comment by justin.j...@gmail.com
on 2 Mar 2015 at 9:05
I would be interested in this as well, since it has forced me to use the "old"
Emitter API. In my mind, YAML should be easily readable, and arbitrary or
inconsistent ordering hinders that.
That said, the old Emitter API does the trick.
Original comment by Skimm...@gmail.com
on 11 Mar 2015 at 5:45
This issue has moved to github: https://github.com/jbeder/yaml-cpp/issues/169
Original comment by jbe...@gmail.com
on 30 Mar 2015 at 1:31
Original issue reported on code.google.com by
rudrapou...@gmail.com
on 26 Jul 2012 at 11:33