-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Home
JSON-Java is a reference application for reading and writing JSON docs in Java. It was written by Douglas Crockford, who first specified the JSON document format. It works by parsing and storing JSON text inside of POJOs - Plain Old Java Objects. This allows your Java code to navigate into the doc, read, update, and write the JSON document.
The primary purpose of this project is to show how to parse and emit JSON documents in Java. There are two primary classes:
- JSONObject: Parse a JSON object from a String, update the JSON, and emit it as a String.
- JSONArray: Parse a JSON array from a String, update the JSON, and emit it as a String.
For the purposes of this project, a JSON doc is a valid JSON text string that begins with '{' or '['. JSON text that consists entirely of a string or primitive type is represented by the corresponding Java type and is not parsed or emitted by this library. If the text string begins with '{', it should be parsed by creating a new JSONObject(String). If the text begins with '[', it should be parsed by creating a new JSONArray(String).
- Create a new JSONObject() and populate the instance by calling put*(), putOpt*(), append(), and accumulate() API methods.
- Create a new JSONArray() and populate the instance by calling put*(), putOpt*(), putAll(), and addAll() API methods.
- JSON text that is accessed via a Reader object can be parsed with a JSONTokener. Here is an example using a JSONObject. The reader should be closed by the calling code after the JSONObject is created.
Reader reader;
/* initialize the reader */
JSONObject jsonObject = new JSONObject(new JSONTokener(reader));
Calling jsonObject.toString() or jsonArray.toString() will cause the instance to emit its contents as a syntactically correct JSON document without blank-space chars. An empty JSONObject will emit "{}". An empty JSONArray will emit "[]". Formatted output can be obtained by calling jsonObject.toString(int) or jsonArray.toString(int), where the int parameter indicates the indentation.
Parsing and converting XML (eXtensible Markup Language) data to JSON (JavaScript Object Notation) in Java is often necessary when dealing with legacy APIs, configuration files, or data formats. This section offers a comprehensive look into how to accomplish this task using the org.json.XML
and XMLParserConfiguration
classes in the JSON-java library.
XML and JSON are inherently different formats, each with their unique features and limitations. For instance, XML supports attributes, complex nesting, and a broad array of data types, while JSON offers a simpler, more streamlined data format. This discrepancy poses several challenges in data conversion.
Transforming XML (eXtensible Markup Language) to JSON (JavaScript Object Notation) can be problematic due to several key differences between the two data formats. Here are some of the main issues that can arise during the conversion:
-
Complexity in XML: XML can represent complex, hierarchical data structures with the use of attributes, nested elements, and namespaces. JSON, while it can also represent nested structures, lacks the same degree of complexity. There's no direct equivalent for attributes or namespaces in JSON. As a result, transforming XML that heavily uses these features into JSON can lead to a loss of information or lead to convoluted JSON structures.
-
Order of Elements: In XML, the order of elements can be significant. For instance, in an XML document representing a book, the order of chapters would be important. However, JSON is primarily based on unordered sets of name/value pairs. While arrays in JSON preserve order, interpreting when to use arrays during the transformation from XML can be an issue.
-
Text and Mixed Content: XML supports mixed content (elements with both text and child elements), while JSON does not have a built-in mechanism for representing this kind of data. This discrepancy can make certain XML documents difficult to representin JSON.
-
Metadata and Schemas: XML has built-in support for schemas (like XML Schema or DTD), which can provide detailed rules about what data an XML document can contain and how it should be structured. JSON lacks a similar, universally accepted schema language. Metadata that's part of the XML document (like namespaces, comments, and processing instructions) might be lost in the conversion to JSON, as JSON doesn't have built-in equivalents for these constructs.
-
Attributes and Namespaces: In XML, elements can have attributes and namespaces, but in JSON, there are no equivalent concepts. This discrepancy can cause a loss of information in the conversion process. Various conversion algorithms handle this differently, such as converting attributes to name/value pairs, but this can create more complex and less intuitive JSON structures.
-
Data Types: XML data is mostly text, while JSON provides more explicit and diverse data types like Boolean, Number, and Null in addition to String. When converting from XML to JSON, you may need to infer the correct data type, which is not always straightforward.
The org.json.XML
class provides a straightforward way to convert XML data into a JSON object. Below is a simple example:
import org.json.XML;
import org.json.JSONObject;
public class Main {
public static void main(String[] args) {
String xmlString = "<book><title>The Catcher in the Rye</title><author>J.D. Salinger</author></book>";
JSONObject jsonObject = XML.toJSONObject(xmlString);
System.out.println(jsonObject.toString(2));
}
}
The XMLParserConfiguration
class allows you to customize how the XML parser behaves. Here's how to use it:
You can create an XMLParserConfiguration
instance with your preferred settings. For example, to preserve all numerical strings as is, set keepStrings
to true
:
XMLParserConfiguration config = new XMLParserConfiguration().withKeepStrings(true);
Use the toJSONObject
method and pass your XMLParserConfiguration
instance:
JSONObject jsonObject = XML.toJSONObject(xmlString, config);
Consider the following XML string:
<person age="30">John Doe</person>
Here's how the conversion will differ based on the keepStrings
setting.
-
Without Custom Configuration
JSONObject jsonObject = XML.toJSONObject("<person age=\"30\">John Doe</person>"); System.out.println(jsonObject.toString());
Output:
{"person": {"age": 30, "content": "John Doe"}}
Notice that the "age" attribute is converted to a number.
-
With Custom Configuration
XMLParserConfiguration config = new XMLParserConfiguration(true); JSONObject jsonObject = XML.toJSONObject("<person age=\"30\">John Doe</person>", config); System.out.println(jsonObject.toString());
Output:
{"person": {"age": "30", "content": "John Doe"}}
In this case, "age" is preserved as a string.
Each XMLParserConfiguration property provides a different way to customize the parser. Attach a property value to the constructor by using 'fluent setter' methods, which can be concatenated together with the constructor, e.g. new XMLParserConfiguration().withKeepStrings(true).withcDataTagName("MyCDATA").
-
withKeepStrings(boolean): If true, values will not be attempted to be converted to a number, boolean, or null.
-
withcDataTagName(String): If not null and not the empty string, this is the name of the XML tag that will be used to store the content of tags that contain CDATA sections.
-
withConvertNilAttributeToNull(boolean): If true, and the nil attribute of a tag is set to true, the value of the tag will be set to a JSONNull object.
-
withXsiTypeMap(Map<String, XMLXsiTypeConverter<?>>): Specifies that the values with attribute xsi:type will be converted to a target type defined in the map.
-
withForceList(Set): Tags listed in the set are converted to JSONArray list entries
- withMaxNestingDepth(int): Defines the maximum nesting depth the parser will descend before throwing an exception. The default is 512.