Boost C++ Libraries: Ticket #5210: JSON writer does not allow attributes and children in the same node https://svn.boost.org/trac10/ticket/5210 <p> The JSON serialization of property_tree is currently restricts to instances of property_tree that do contain data attributes only in leaf node. </p> <div class="wiki-code"><div class="code"><pre> <span class="c1">// Verify if ptree does not contain information that cannot be written to json</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Ptree</span><span class="o">&gt;</span> <span class="kt">bool</span> <span class="n">verify_json</span><span class="p">(</span><span class="k">const</span> <span class="n">Ptree</span> <span class="o">&amp;</span><span class="n">pt</span><span class="p">,</span> <span class="kt">int</span> <span class="n">depth</span><span class="p">)</span> <span class="p">{</span> <span class="k">typedef</span> <span class="k">typename</span> <span class="n">Ptree</span><span class="o">::</span><span class="n">key_type</span><span class="o">::</span><span class="n">value_type</span> <span class="n">Ch</span><span class="p">;</span> <span class="k">typedef</span> <span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o">&lt;</span><span class="n">Ch</span><span class="o">&gt;</span> <span class="n">Str</span><span class="p">;</span> <span class="c1">// Root ptree cannot have data</span> <span class="k">if</span> <span class="p">(</span><span class="n">depth</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pt</span><span class="p">.</span><span class="k">template</span> <span class="n">get_value</span><span class="o">&lt;</span><span class="n">Str</span><span class="o">&gt;</span><span class="p">().</span><span class="n">empty</span><span class="p">())</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">// Ptree cannot have both children and data</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">pt</span><span class="p">.</span><span class="k">template</span> <span class="n">get_value</span><span class="o">&lt;</span><span class="n">Str</span><span class="o">&gt;</span><span class="p">().</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">pt</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">// Check children</span> <span class="k">typename</span> <span class="n">Ptree</span><span class="o">::</span><span class="n">const_iterator</span> <span class="n">it</span> <span class="o">=</span> <span class="n">pt</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="k">for</span> <span class="p">(;</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">pt</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">verify_json</span><span class="p">(</span><span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">,</span> <span class="n">depth</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">// Success</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> To me this is a random limitation. I removed it locally and tried to generate an instance with attributes and children: </p> <pre class="wiki">{ "Object":{ "Name": "Object Name", "Child": { "Name": "Child Name" } } } </pre><p> It works well. Why is this policy built into the json writer? Why is there no way to deactivate this policy? </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5210 Trac 1.4.3 Sebastian Redl Wed, 23 Feb 2011 16:17:39 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5210#comment:1 https://svn.boost.org/trac10/ticket/5210#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> A property tree node can have both data and children, i.e. a tree can look like this: </p> <pre class="wiki">root: &lt;- has only children child1: "child 1 data" &lt;- has both data and children child1.1: "child 1.1 data" &lt;- has only data child1.2: "child 1.2 data" &lt;- has only data child2: "child 2 data" &lt;- has only data </pre><p> There is no way to represent such a tree as JSON. A JSON node can be an object (it has named children), an array (it has unnamed children), or a basic data item (string, number, boolean, null). There is no JSON node that can have both direct data and children. </p> <p> Therefore, the validation function rejects such trees when generating JSON. </p> Ticket anonymous Wed, 18 May 2011 15:31:51 GMT attachment set https://svn.boost.org/trac10/ticket/5210 https://svn.boost.org/trac10/ticket/5210 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">test_property_tree.cpp</span> </li> </ul> Ticket anonymous Wed, 18 May 2011 15:32:03 GMT attachment set https://svn.boost.org/trac10/ticket/5210 https://svn.boost.org/trac10/ticket/5210 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">Shop.xml</span> </li> </ul> Ticket Christian Ceelen <christian.ceelen@…> Wed, 18 May 2011 15:34:07 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/5210#comment:2 https://svn.boost.org/trac10/ticket/5210#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> Thanks. I see this check is mandatory. I was poking into this function only for the sole reason that the error indicated it while i was playing a simple XML to JSON conversion. For instance: </p> <pre class="wiki">&lt;object&gt; &lt;type&gt;Shop&lt;/type&gt; &lt;POC&gt; &lt;name&gt;Private Investigation&lt;/name&gt; &lt;street&gt;221B Baker Street&lt;/street&gt; &lt;town&gt;London&lt;/town&gt; &lt;zip&gt;NW1 6XE&lt;/zip&gt; &lt;country&gt;United Kingdom&lt;/country&gt; &lt;/POC&gt; &lt;workingDays&gt; &lt;Monday/&gt; &lt;Saturday/&gt; &lt;Sunday/&gt; &lt;/workingDays&gt; &lt;/object&gt; </pre><p> This simple XML file is read in without any trouble. But if i walk through the resulting ptree and print all key and value contents, then it looks like this: </p> <pre class="wiki">object: " " type: "Private Investigation" POC: " " name: "Cabbies United" street: "221B Baker Street" town: "London" zip: "NW1 6XE" country: "United Kingdom" workingDays: " " Monday: "" Saturday: "" Sunday: "" </pre><p> The attempt to serialize in JSON this ptree fails, because of the empty strings stored in the value fields of the keys object, POC, and workingDays. As the original XML has no attributes for these tags i am quite puzzled where these are coming from. </p> <p> See the attached files for the small test i wrote. This fails for version 1.46.0 and 1.46.1. </p> Ticket Sebastian Redl Wed, 18 May 2011 18:05:03 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5210#comment:3 https://svn.boost.org/trac10/ticket/5210#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> Your XML contains whitespace between the various elements, and it is preserved. Therefore, the nodes contain both data and children, which, as mentioned, is not allowed for the JSON writer. </p> <p> Pass trim_whitespace to read_xml, and it should collapse and remove the whitespace. </p> Ticket