Création de tableaux JSON dans Boost en utilisant des arbres de propriétés

j'essaie de créer un tableau JSON en utilisant des arbres de propriétés boost.

la documentation dit:" les réseaux JSON sont mappés aux noeuds. Chaque élément est un nœud enfant avec un nom vide."

donc j'aimerais créer un arbre de propriétés avec des noms vides, puis appeler write_json(...) pour obtenir le tableau. Cependant, la documentation ne me dit pas comment créer des noeuds enfants anonymes. J'ai essayé ptree.add_child("", value) , mais cela donne:

Assertion `!p.empty() && "Empty path not allowed for put_child."' failed

la documentation ne semble pas aborder ce point, du moins pas d'une manière que je puisse comprendre. Quelqu'un peut-il aider?

60
demandé sur 2NinerRomeo 2010-01-22 04:58:14

4 réponses

Tableau Simple:

#include <boost/property_tree/ptree.hpp>
using boost::property_tree::ptree;

ptree pt;
ptree children;
ptree child1, child2, child3;

child1.put("", 1);
child2.put("", 2);
child3.put("", 3);

children.push_back(std::make_pair("", child1));
children.push_back(std::make_pair("", child2));
children.push_back(std::make_pair("", child3));

pt.add_child("MyArray", children);

write_json("test1.json", pt);

résultats dans:

{
    "MyArray":
    [
        "1",
        "2",
        "3"
    ]
}

tableau sur les objets:

ptree pt;
ptree children;
ptree child1, child2, child3;


child1.put("childkeyA", 1);
child1.put("childkeyB", 2);

child2.put("childkeyA", 3);
child2.put("childkeyB", 4);

child3.put("childkeyA", 5);
child3.put("childkeyB", 6);

children.push_back(std::make_pair("", child1));
children.push_back(std::make_pair("", child2));
children.push_back(std::make_pair("", child3));

pt.put("testkey", "testvalue");
pt.add_child("MyArray", children);

write_json("test2.json", pt);

résultats dans:

{
    "testkey": "testvalue",
    "MyArray":
    [
        {
            "childkeyA": "1",
            "childkeyB": "2"
        },
        {
            "childkeyA": "3",
            "childkeyB": "4"
        },
        {
            "childkeyA": "5",
            "childkeyB": "6"
        }
    ]
}

espérons que cette aide

90
répondu JustAnotherLinuxNewbie 2015-04-05 14:43:26

ce que vous devez faire est ce morceau de plaisir. C'est de mémoire, mais quelque chose comme ça marche pour moi.

boost::property_tree::ptree root;
boost::property_tree::ptree child1;
boost::property_tree::ptree child2;

// .. fill in children here with what you want
// ...

ptree.push_back( std::make_pair("", child1 ) );
ptree.push_back( std::make_pair("", child2 ) );

mais attention il y a plusieurs bugs dans le JSON parsing et l'écriture. Plusieurs d'entre elles pour lesquelles j'ai soumis des rapports de bogue - sans réponse: (

EDIT: pour répondre inquiet à ce sujet, la sérialisation de manière incorrecte en tant que {"":"","":""}

cela ne se produit que lorsque le tableau est l'élément racine. Le boost ptree l'auteur traite tous les éléments de la racine comme des objets-jamais des tableaux ou des valeurs. Ceci est causé par la ligne suivante dans boost/propert_tree/detail/json_parser_writer.HPP

else if (indent > 0 && pt.count(Str()) == pt.size())

Se débarrasser de la "indent > 0 &&" permettra d'écrire des tableaux correctement.

si vous n'aimez pas combien d'espace est produit, vous pouvez utiliser le patch que j'ai fourni ici

19
répondu Michael Anderson 2013-12-04 07:22:30

lorsque j'ai commencé à utiliser L'Arbre de propriété pour représenter une structure JSON, j'ai rencontré des problèmes similaires que je n'ai pas résolus. Notez également que dans la documentation, l'arborescence des propriétés ne supporte pas entièrement les informations de type:

Les valeurs

JSON sont mappées aux noeuds contenant la valeur. Cependant, toutes les informations de type sont Perdues; Les nombres, ainsi que les littérales "null", "true" et "false" sont simplement mappés à leur forme de chaîne.

après avoir appris cela, je suis passé à l'implémentation plus complète de JSON JSON Spirit . Cette bibliothèque utilise Boost Spirit pour la mise en œuvre de la grammaire JSON et prend entièrement en charge JSON y compris les tableaux.

je vous suggère d'utiliser une implémentation alternative C++ JSON.

11
répondu Yukiko 2016-06-25 20:15:46

dans mon cas je voulais ajouter un tableau à un emplacement plus ou moins arbitraire, donc, comme la réponse de Michael, créer un arbre enfant et le peupler avec des éléments de tableau:

using boost::property_tree::ptree;

ptree targetTree;
ptree arrayChild;
ptree arrayElement;

//add array elements as desired, loop, whatever, for example
for(int i = 0; i < 3; i++)
{
  arrayElement.put_value(i);
  arrayChild.push_back(std::make_pair("",arrayElement))
}

lorsque l'enfant a été peuplé, utilisez la fonction put_child() ou add_child() pour ajouter l'arbre entier à l'arbre cible, comme ceci...

targetTree.put_child(ptree::path_type("target.path.to.array"),arrayChild)

la fonction put_child prend un chemin et un arbre pour un argument et va "greffer" arrayChild dans targetTree

6
répondu 2NinerRomeo 2012-04-11 23:56:45