Как использовать yaml-cpp для создания сложной структуры данных? - PullRequest
1 голос
/ 02 сентября 2011

Этот вопрос адресован, главным образом, автору yaml-cpp (Джесси Бедер), который попросил опубликовать здесь вопросы, касающиеся использования yaml-cpp.

В ряде мест, включая документацию yaml-cpp, http://code.google.com/p/yaml-cpp/wiki/HowToEmitYAML#Using_Existing_Nodes

Вы упомянули, что yaml-cpp не предоставляет способ изменить существующие объекты YAML :: Node в памяти, и вы предлагаете изменить YAML в памяти:

  1. Используйте мою собственную структуру данных, чтобы сохранить YAML в памяти, а затем каким-то образом передать его обратно в yaml-cpp при сериализации (что, по сути, сводится к повторному воплощению полиморфизма в YAML :: Node и не сильно отличается от переопределения большей части yaml-cpp), или

  2. "в настоящее время лучший способ сделать это - использовать Emitter и выбирать и выбирать из дочерних узлов вашего узла", т.е. пример, приведенный в документации. Проблема такого подхода в том, что он хорошо работает только в самых простых случаях. Предположим, я хочу добавить элемент в последовательность карт, где одним из элементов карты является сам список? Это может быть произвольно усложнено очень быстро! Чтобы найти, куда вставить новые данные, испуская манипуляторы, все это должно быть сделано «вручную».

Чтобы усугубить проблему, Emitter является средством форматирования, и его единственным выходным значением является строка, поэтому мой единственный вариант - создать весь документ YAML с моими изменениями, а затем заново проанализировать его в новом представлении в памяти. Если я внесу много изменений в документ, эффективность этой операции быстро возрастет.

Я понимаю, что изменение существующего узла сопряжено с трудностями реализации (что вы делаете с существующими ссылками на данные узла или данные дочерних узлов?). Тем не менее, мне кажется, что создание новых автономных узлов на лету и вставка их в дерево в памяти должно быть как минимум простым. Вот, например, как реализован JsonCpp: http://jsoncpp.sourceforge.net

Это, по крайней мере, позволит подходу "излучатель", который вы документируете, стать потенциально жизнеспособным обходным путем, если неэффективным.

Буду признателен за ваши мысли по этим вопросам. К сожалению, эти ограничения довольно серьезны, и, учитывая, что yaml-cpp является единственной C ++ / OO библиотекой YAML, я задаюсь вопросом, есть ли практическая альтернатива, кроме перехода на JSON.

Большое спасибо заранее за ваши мысли!

1 Ответ

1 голос
/ 02 сентября 2011

Тем не менее, мне кажется, что создание новых автономных узлов на лету и их вставка в дерево в памяти, по крайней мере, должны быть простыми.

Я бы хотел сделать это (и я посмотрел на JsonCpp здесь), но есть три проблемы:

  1. Существует разница между YAML и JSON: YAML различает нулевой узел и несуществующий узел.

  2. Текущее поведение yaml-cpp - генерировать исключение при запросе несуществующего узла.

  3. В YAML отображения могут иметь произвольные ключи.

Для проблемы # 2 это означает, что, скорее всего, нам придется (в основном!) Нарушить текущее поведение, что заставляет меня колебаться нажимать на курок.

Например, в JsonCpp, когда вы пишете

 root["encoding"];

создаст для вас узел по умолчанию, если он не существует. В yaml-cpp будет выброшено исключение, если оно не существует. Люди могут полагаться на код, который выглядит следующим образом:

try {
  root["encoding"]; // etc
catch(const YAML::Exception&) {
  // does not exist
}

Наконец, для проблемы # 3, как бы вы указали ключ, который является отображением? И если кто-то написал

root[1] = 5;

будет ли это создавать экземпляр root как последовательность с нулевым первым элементом или отображение с одной парой ключ / значение {1, 5}? Если это последнее (что кажется более естественным), то

root[0] = 3;
root[1] = 5;

и

root[1] = 5;
root[0] = 3;

будет иметь другое поведение, которое будет нелогичным.

По сути, суть в том, что я думал об этом, но я не смог придумать достаточно хороший API для этого. Я хотел бы сделать это, поэтому, если у вас есть какие-либо мысли, пожалуйста, дайте мне знать.

Тем не менее, я не уверен, что stackoverflow - лучшее место для такого обсуждения (я написал это на сайте yaml-cpp, потому что многие люди публиковали практические вопросы в вики) - так что не стесняйтесь чтобы отправить мне письмо (оно на моей странице пользователя).

...