72 votes

Création de tableaux JSON dans Boost à l'aide d'arbres de propriétés

Je suis en train de créer un tableau JSON à l'aide de boost propriété des arbres.

La documentation dit: "JSON tableaux sont mappés à des nœuds. Chaque élément est un nœud enfant avec un nom vide."

Donc je voudrais créer une propriété de l'arbre avec vide noms, puis appelez write_json(...) pour obtenir la matrice de sortie. Toutefois, la documentation n'est pas dis-moi comment faire pour créer sans nom nœuds enfants. J'ai essayé d' 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, au moins pas de toute façon je peux comprendre. Quelqu'un peut-il aider?

122voto

Tableau simple:

 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ésulte en:

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

Tableau sur 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ésulte en:

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

J'espère que cela t'aides

22voto

Michael Anderson Points 21181

Ce que vous devez faire est de cette pièce de plaisir. C'est à partir de la mémoire, mais quelque chose comme cela fonctionne 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 l'analyse et de l'écriture. Plusieurs de qui je l'ai soumis des rapports de bogues pour - avec pas de réponse :(

EDIT: à l'adresse de souci, c'sérialisation de manière incorrecte en tant que {"":"","":""}

Cela se produit uniquement lorsque le tableau est l'élément racine. Le coup de pouce ptree écrivain traite tous les éléments racines comme des objets - ne jamais tableaux ou des valeurs. Ceci est causé par la ligne suivante dans boost/propert_tree/detail/json_parser_writer.php

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 la façon dont l'espace est produit, vous pouvez utiliser le patch que j'ai fourni ici

12voto

Yukiko Points 858

Lors du démarrage d'utilisation de la Propriété de l'Arbre pour représenter une structure JSON, j'ai rencontré des problèmes similaires que je n'ai pas de résoudre. Notez aussi qu'à partir de la documentation, de la propriété de l'arbre n'est pas entièrement en charge les informations de type:

JSON valeurs sont mappés à des nœuds contenant la valeur. Cependant, tout type d'information est perdue; les nombres, ainsi que les littéraux "null", "vrai" et "faux" sont simplement transformés en leur la forme d'une chaîne.

Après avoir appris cela, je suis passé à la plus complète de l'implémentation JSON JSON Esprit. Cette bibliothèque utilise Boost Esprit pour le JSON de la grammaire de la mise en œuvre et soutient pleinement JSON y compris les tableaux.

Je vous suggère d'utiliser une variante C++ JSON mise en œuvre. Voir le Dépassement de Pile question Quel est le meilleur C++ parser JSON? pour certaines solutions de rechange à JSON Esprit.

6voto

2NinerRomeo Points 737

Dans mon cas, je voulais ajouter un tableau à une plus ou moins arbitraire, de sorte que, à l'instar de Michael réponse, créez un enfant un arbre et de le remplir avec les éléments du 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é rempli, l'utilisation de l' put_child() ou add_child() fonction pour ajouter la totalité de l'enfant de l'arbre à l'arbre, comme ça...

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

le put_child fonction prend un chemin d'accès et un arbre pour un argument et "la greffe" arrayChild en targetTree

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X