@@ -328,7 +328,7 @@ public void shouldHandleNullNodeValue()
328328 JSONObject inputJSON = new JSONObject ();
329329 inputJSON .put ("nullValue" , JSONObject .NULL );
330330 // This is a possible preferred result
331- String expectedXML = "<nullValue/>" ;
331+ // String expectedXML = "<nullValue/>";
332332 /**
333333 * This is the current behavior. JSONObject.NULL is emitted as
334334 * the string, "null".
@@ -337,4 +337,89 @@ public void shouldHandleNullNodeValue()
337337 String resultXML = XML .toString (inputJSON );
338338 assertEquals (actualXML , resultXML );
339339 }
340- }
340+
341+ @ Test
342+ public void contentOperations () {
343+ /**
344+ * Make sure we understand exactly how the "content" keyword works
345+ */
346+
347+ /**
348+ * When a standalone <!CDATA[...]] structure is found while parsing XML into a
349+ * JSONObject, the contents are placed in a string value with key="content".
350+ */
351+ String xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2>" ;
352+ JSONObject jsonObject = XML .toJSONObject (xmlStr );
353+ assertTrue ("1. 3 items" , 3 == jsonObject .length ());
354+ assertTrue ("1. empty tag1" , "" .equals (jsonObject .get ("tag1" )));
355+ assertTrue ("1. empty tag2" , "" .equals (jsonObject .get ("tag2" )));
356+ assertTrue ("1. content found" , "if (a < b && a > 0) then return" .equals (jsonObject .get ("content" )));
357+
358+ // multiple consecutive standalone cdatas are accumulated into an array
359+ xmlStr = "<tag1></tag1><![CDATA[if (a < b && a > 0) then return]]><tag2></tag2><![CDATA[here is another cdata]]>" ;
360+ jsonObject = XML .toJSONObject (xmlStr );
361+ assertTrue ("2. 3 items" , 3 == jsonObject .length ());
362+ assertTrue ("2. empty tag1" , "" .equals (jsonObject .get ("tag1" )));
363+ assertTrue ("2. empty tag2" , "" .equals (jsonObject .get ("tag2" )));
364+ assertTrue ("2. content array found" , jsonObject .get ("content" ) instanceof JSONArray );
365+ JSONArray jsonArray = jsonObject .getJSONArray ("content" );
366+ assertTrue ("2. array size" , jsonArray .length () == 2 );
367+ assertTrue ("2. content array entry 1" , "if (a < b && a > 0) then return" .equals (jsonArray .get (0 )));
368+ assertTrue ("2. content array entry 2" , "here is another cdata" .equals (jsonArray .get (1 )));
369+
370+ /**
371+ * text content is accumulated in a "content" inside a local JSONObject.
372+ * If there is only one instance, it is saved in the context (a different JSONObject
373+ * from the calling code. and the content element is discarded.
374+ */
375+ xmlStr = "<tag1>value 1</tag1>" ;
376+ jsonObject = XML .toJSONObject (xmlStr );
377+ assertTrue ("3. 2 items" , 1 == jsonObject .length ());
378+ assertTrue ("3. value tag1" , "value 1" .equals (jsonObject .get ("tag1" )));
379+
380+ /**
381+ * array-style text content (multiple tags with the same name) is
382+ * accumulated in a local JSONObject with key="content" and value=JSONArray,
383+ * saved in the context, and then the local JSONObject is discarded.
384+ */
385+ xmlStr = "<tag1>value 1</tag1><tag1>2</tag1><tag1>true</tag1>" ;
386+ jsonObject = XML .toJSONObject (xmlStr );
387+ assertTrue ("4. 1 item" , 1 == jsonObject .length ());
388+ assertTrue ("4. content array found" , jsonObject .get ("tag1" ) instanceof JSONArray );
389+ jsonArray = jsonObject .getJSONArray ("tag1" );
390+ assertTrue ("4. array size" , jsonArray .length () == 3 );
391+ assertTrue ("4. content array entry 1" , "value 1" .equals (jsonArray .get (0 )));
392+ assertTrue ("4. content array entry 2" , jsonArray .getInt (1 ) == 2 );
393+ assertTrue ("4. content array entry 2" , jsonArray .getBoolean (2 ) == true );
394+
395+ /**
396+ * Complex content is accumulated in a "content" field. For example, an element
397+ * may contain a mix of child elements and text. Each text segment is
398+ * accumulated to content.
399+ */
400+ xmlStr = "<tag1>val1<tag2/>val2</tag1>" ;
401+ jsonObject = XML .toJSONObject (xmlStr );
402+ assertTrue ("5. 1 item" , 1 == jsonObject .length ());
403+ assertTrue ("5. jsonObject found" , jsonObject .get ("tag1" ) instanceof JSONObject );
404+ jsonObject = jsonObject .getJSONObject ("tag1" );
405+ assertTrue ("5. 2 contained items" , 2 == jsonObject .length ());
406+ assertTrue ("5. contained tag" , "" .equals (jsonObject .get ("tag2" )));
407+ assertTrue ("5. contained content jsonArray found" , jsonObject .get ("content" ) instanceof JSONArray );
408+ jsonArray = jsonObject .getJSONArray ("content" );
409+ assertTrue ("5. array size" , jsonArray .length () == 2 );
410+ assertTrue ("5. content array entry 1" , "val1" .equals (jsonArray .get (0 )));
411+ assertTrue ("5. content array entry 2" , "val2" .equals (jsonArray .get (1 )));
412+
413+ /**
414+ * If there is only 1 complex text content, then it is accumulated in a
415+ * "content" field as a string.
416+ */
417+ xmlStr = "<tag1>val1<tag2/></tag1>" ;
418+ jsonObject = XML .toJSONObject (xmlStr );
419+ assertTrue ("6. 1 item" , 1 == jsonObject .length ());
420+ assertTrue ("6. jsonObject found" , jsonObject .get ("tag1" ) instanceof JSONObject );
421+ jsonObject = jsonObject .getJSONObject ("tag1" );
422+ assertTrue ("6. contained content found" , "val1" .equals (jsonObject .get ("content" )));
423+ assertTrue ("6. contained tag2" , "" .equals (jsonObject .get ("tag2" )));
424+ }
425+ }
0 commit comments