C++ header-only converter from Json to XML, based in also header-only nlohmann json library.
-
All future xml attributes, are expected to be prefixed. By default '@' is used (you can change it at
JsonSaxConsumer
constructor), like python xmltodict project does. -
XML text is not supported, so for example key nodes "#text" (default used by xmltodict) is not managed and hence fails as not prefixed like commented above.
-
XML namespaces are also not expected, and user must expand equivalent top nodes to represent the scope desired.
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>
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.
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)
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)
$> cmake .
$> make
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 !
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:
$> examples/json2xml examples/test.json | tee -a text.xml
This will output the xml representation, or an error.
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
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"
$> docker build -f ct/Dockerfile . -t ct_image:latest
$> docker run --rm -v $PWD:/code -w /code/ct ct_image:latest
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}