c++ - Crear matrices JSON en Boost usando árboles de propiedades
boost-propertytree (4)
Intento crear una matriz JSON utilizando los árboles de propiedades boost.
La documentation dice: "Las matrices JSON se asignan a los nodos. Cada elemento es un nodo secundario con un nombre vacío".
Entonces me gustaría crear un árbol de propiedades con nombres vacíos, luego llamar a write_json(...)
para sacar el conjunto. Sin embargo, la documentación no me dice cómo crear nodos secundarios sin nombre. Intenté ptree.add_child("", value)
, pero esto produce:
Assertion `!p.empty() && "Empty path not allowed for put_child."'' failed
La documentación no parece abordar este punto, al menos no de ninguna manera que pueda entender. ¿Alguien puede ayudar?
Arreglo 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);
resultados en:
{
"MyArray":
[
"1",
"2",
"3"
]
}
Matriz sobre objetos:
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);
resultados en:
{
"testkey": "testvalue",
"MyArray":
[
{
"childkeyA": "1",
"childkeyB": "2"
},
{
"childkeyA": "3",
"childkeyB": "4"
},
{
"childkeyA": "5",
"childkeyB": "6"
}
]
}
espero que esto ayude
Cuando comencé a usar Property Tree para representar una estructura JSON, encontré problemas similares que no resolví. También tenga en cuenta que a partir de la documentación, el árbol de propiedades no es totalmente compatible con la información de tipo:
Los valores JSON se asignan a nodos que contienen el valor. Sin embargo, se pierde toda la información de tipo; los números, así como los literales "nulo", "verdadero" y "falso" simplemente se asignan a su forma de cadena.
Después de aprender esto, cambié a la implementación más completa JSON Spirit . Esta biblioteca utiliza Boost Spirit para la implementación de la gramática JSON y es totalmente compatible con JSON, incluidas las matrices.
Le sugiero que use una implementación C ++ JSON alternativa.
En mi caso, quería agregar una matriz a una ubicación más o menos arbitraria, así que, al igual que la respuesta de Michael, crea un árbol hijo y rellena con elementos de la matriz:
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))
}
Cuando el niño haya sido poblado, use la función put_child()
o add_child()
para agregar el árbol secundario completo al árbol de destino, como este ...
targetTree.put_child(ptree::path_type("target.path.to.array"),arrayChild)
la función put_child toma una ruta y un árbol para un argumento y "injerta" arrayChild en targetTree
Lo que debes hacer es esta diversión. Esto es de memoria, pero algo como esto me funciona.
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 ) );
Pero ten en cuenta que hay varios errores en el análisis y la escritura json. Varios de los cuales he enviado informes de fallas, sin respuesta :(
EDITAR: para abordar la preocupación sobre la serialización incorrecta como {"": "", "": ""}
Esto solo ocurre cuando la matriz es el elemento raíz. El escritor de ptree boost trata todos los elementos raíz como objetos, nunca matrices o valores. Esto es causado por la siguiente línea en boost / propert_tree / detail / json_parser_writer.hpp
else if (indent > 0 && pt.count(Str()) == pt.size())
Deshacerse del "sangrado> 0 &&" le permitirá escribir matrices correctamente.
Si no le gusta la cantidad de espacio que se produce, puede usar el parche que he proporcionado here