json2xml
C++ json2xml converter

C++ header-only converter from Json to XML, based in also header-only nlohmann json library.

Restrictions

In summary, this converter is intended to be used for simple xml configurations with predictable and controlled content:

{
"grandfather": {
"father": {
"child": [
{
"@name": "Jose",
"@bestFriend": "Maria"
},
{
"@name": "Maria",
"@bestFriend": "Jose"
}
],
"student": {
"@favoriteBook": "The Gods Themselves",
"@age": "21"
}
}
}
}

turns into:

<grandfather>
<father>
<child name="Jose" bestFriend="Maria"/>
<child name="Maria" bestFriend="Jose"/>
<student favoriteBook="The Gods Themselves" age="21"/>
</father>
</grandfather>

Integration

json2xml.hpp is the single required file in include/ert or released here. You need to add

#include <ert/json2xml.hpp> // or any other desired location within your project

You must also integrate nlohmann/json header-only file (json.hpp) in your project.

CMake

Embedded

To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call add_subdirectory() in your CMakeLists.txt file:

# Typically you don't care so much for a third party library's examples to be
# run from your own project's code.
set(ERT_JSON2XML_BuildExamples OFF CACHE INTERNAL "")
add_subdirectory(ert_json2xml)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE ert_json2xml::ert_json2xml)
Embedded (FetchContent)

Since CMake v3.11, FetchContent can be used to automatically download the repository as a dependency at configure type.

Example:

include(FetchContent)
FetchContent_Declare(ert_json2xml
GIT_REPOSITORY https://github.com/testillano/json2xml.git
GIT_TAG v1.0.1)
FetchContent_GetProperties(ert_json2xml)
if(NOT ert_json_POPULATED)
FetchContent_Populate(ert_json2xml)
add_subdirectory(${ert_json2xml_SOURCE_DIR} ${ert_json2xml_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
target_link_libraries(foo PRIVATE ert_json2xml::ert_json2xml)

Build example and test natively

Build

$> cmake .
$> make

Component test

CICD is tested with Codefresh. For local component test, on ubuntu you will need python3, pip3 and pytest & xmltodict modules:

$> apt-get update && apt-get install -y python3 python3-pip
$> pip3 install pytest xmltodict

Then, you shall change directory to ct and just execute pytest:

$> cd ct
$> pytest

Don't forget to build the project first !

Execute example

A converter example based in the library header is located at example directory:

$> examples/json2xml
$> Usage: json2xml <json file>

There are also some test files (test.<n>.json) to play with:

Passing file

$> examples/json2xml examples/test.json | tee -a text.xml

This will output the xml representation, or an error.

Reverse check

You could do the opposite (xml to json) using python xmltodict module:

$> python3 util/xml2json.py test.xml

You can also use this beautify perl script for json output, courtesy of yanOnGithub:

$> python3.9 util/xml2json.py test.xml | perl util/beautifyJson.perl

Build and test with docker

Build

You may remove cmake cache from native workflow described above:

$> find . -name CMakeCache.txt -exec rm {} \;

Or perhaps you could execute:

$> git clean -xdf

Now, you will build the compilation docker image, and then build:

$> docker build -f dev/Dockerfile . -t dev_image:latest
$> docker run --rm -v $PWD:/code -w /code dev_image:latest bash -c "cmake . && make"

Component test

$> docker build -f ct/Dockerfile . -t ct_image:latest
$> docker run --rm -v $PWD:/code -w /code/ct ct_image:latest

Contributing

Please, execute astyle formatting (using frankwolf image) before any pull request:

$> sources=$(find . -name "*.hpp" -o -name "*.cpp")
$> docker run -it --rm -v $PWD:/data frankwolf/astyle ${sources}