c++jsonboostboost-propertytree

Boost read_json is not working with wptree from std::wstring


I have a simple code which is not working and I don't really know why... here it's:

std::wstring CDbFilterSerializer::DeserializeFromString(const std::wstring& jsonStr)
{
    std::wistringstream ss{ jsonStr };
    boost::property_tree::read_json(ss, m_root);
    return m_root.data();
}

The problem here is that after calling m_root.read_json(...) the wptre object is empty. The return statement is an example, cause the real code after populating the wptree object, I call m_root.get("MyKey") to start reading values and this throw an exception cause the object is empty.

The json received as parameter is:

{
"type":{
      "className":"NumericFilterSerializerHelper: NumericType => unsigned int, DbSerializer => class CDbFilterSerializerByNumericValue",
      "description":""
   },
   "data":{
      "int_number":"45"
   }
}

Is there something wrong here?


Solution

  • Yes. The assumptions are wrong. .data() returns the value at the root node, which is empty (since it's an object). You can print the entire m_tree to see:

    Live On Coliru

    #include <boost/property_tree/json_parser.hpp>
    #include <iostream>
    
    struct CDbFilterSerializer {
        std::wstring DeserializeFromString(const std::wstring& jsonStr);
    
        boost::property_tree::wptree m_root;
    };
    
    std::wstring CDbFilterSerializer::DeserializeFromString(const std::wstring& jsonStr)
    {
        std::wistringstream ss{ jsonStr };
        read_json(ss, m_root);
        return m_root.data();
    }
    
    int main() {
        CDbFilterSerializer obj;
        obj.DeserializeFromString(LR"({
    "type":{
          "className":"NumericFilterSerializerHelper: NumericType => unsigned int, DbSerializer => class CDbFilterSerializerByNumericValue",
          "description":""
       },
       "data":{
          "int_number":"45"
       }
    })");
    
        write_json(std::wcout, obj.m_root, true);
    }
    

    Which prints

    {
        "type": {
            "className": "NumericFilterSerializerHelper: NumericType => unsigned int, DbSerializer => class CDbFilterSerializerByNumericVa
    lue",
            "description": ""
        },
        "data": {
            "int_number": "45"
        }
    }
    

    As you can see the object is not empty. You probably have the path misspelled (we can't tell because MyKey is not in your document).

    SIDE NOTE

    Do not abuse Property Tree for JSON "support". Instead use a JSON library! Boost JSON exists. Several others are freely available.