F# Data: Converting between JSON and XML
This tutorial shows how to implement convert JSON document (represented using
JsonValue type discussed in JSON parser article) to an
XML document (represented as
XElement) and the other way round.
This functionality is not directly available in the F# Data library, but it can
be very easily implemented by recursively walking over the JSON (or XML) document.
If you want to use the JSON to/from XML conversion in your code, you can copy the source from GitHub and just include it in your project. If you use these functions often and would like to see them in the F# Data library, please submit a feature request.
We will be using the LINQ to XML API (available in
System.Xml.Linq.dll) and the
JsonValue which is available in the
1: 2: 3: 4:
In this script, we create a conversion that returns an easy to process value, but the conversion is not reversible (e.g. converting JSON to XML and then back to JSON will produce a different value).
Converting XML to JSON
Although XML and JSON are quite similar formats, there is a number of subtle differences. In particular, XML distinguishes between attributes and child elements. Moreover, all XML elements have a name, while JSON arrays or records are anonymous (but records have named fields). Consider, for example, the following XML:
1: 2: 3: 4: 5:
The JSON that we produce will ignore the top-level element name (
channel). It produces
a record that contains a unique field for every attribute and a name of a child element.
If an element appears multiple times, it is turned into an array:
1: 2: 3: 4:
As you can see, the
item element has been automatically pluralized to
items and the
array contains two record values that consist of the
The conversion function is a recursive function that takes a
XElement and produces
JsonValue. It builds JSON records (using
JsonValue.Record) and arrays (using
JsonValue.Array). All attribute values are turned into
JsonValue.String - the
sample does not imlement more sophisticated conversion that would turn numeric
attributes to a corresponding JSON type:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
Converting JSON to XML
When converting JSON value to XML, we fact the same mismatch. Consider the following JSON value:
1: 2: 3:
The top-level record does not have a name, so our conversion produces a list of
values that can be wrapped into an
XElement by the user (who has to specify the root
name). Record fields that are a primitive value are turned into attributes, while
complex values (array or record) become objects:
1: 2: 3: 4: 5: 6: 7:
The conversion function is, again, implemented as a recursive function. This time, we use
pattern matching to distinguish between the different possible cases of
The cases representing a primitive value simply return the value as
obj, while array
and record construct nested element(s) or attribute:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
F# Data: JSON Parser - a tutorial that introduces
JsonValuefor working with JSON values dynamically.
- F# Data: JSON Type Provider - discusses F# type provider that provides type-safe access to JSON data.
- F# Data: XML Type Provider - discusses the F# type provider that provides type-safe access to XML data.