The REXSapi library is a C++ implementation of the REXS specification. It features high level abstractions for REXS models and provides classes to load, access, create, and store REXS models. Additionally, the API tries to check the model for standard compliance and will report on found issues.
The project is now released and is already used in production.
The library uses REXS database model files in order to validate REXS model files. Database model files can be downloaded from the REXS database page. Currently, the implementation supports versions 1.0 to 1.6, but newer database files should also work. Version 1.0 to 1.6 database model files in english and german can also be found in the models directory of this project.
The library supports REXS model files in xml and json format. Compressed REXS zip archives can also be loaded. The loading and storing mechanism can be easily extended to support other sources besides files for model loading and storing.
The library can be used on
- Linux
- Windows
- Mac OS X
You need a C++17 compatible compiler to use the library. The library should also build with C++20 and C++23.
In order to use REXSapi it is most convinient to just include the Rexsapi.hxx
header. Mind that you have to include this header along the REXSAPI_MINIZ_IMPL
define right before the include in exactly one compilation unit (cpp file) in order to add the miniz implementation to the project.
#define REXSAPI_MINIZ_IMPL
#include <rexsapi/Rexsapi.hxx>
Loading a REXS model file is straight forward. You need the REXS database model files for the API to validate the model.
const rexsapi::TModelLoader loader{"/path/to/rexs/database/models"};
rexsapi::TResult result;
const std::optional<rexsapi::TModel> model =
loader.load("/path/to/your/rexs/model/file", result, rexsapi::TMode::STRICT_MODE);
if (result) {
std::cout << "sucessfully loaded REXS model\n";
} else {
std::cerr << "failed to load REXS model\n";
for (const auto& issue : result.getErrors()) {
std::cerr << issue.getMessage() << "\n";
}
}
The TModelLoader
class can load json and xml REXS model files. If successful, the result will convert to true and the model optional will contain a model. In case of a failure, the result will contain a collection of messages describing the issues. The issues can either be errors or warnings. It is perfectly possible that the result converts to false, a failure, but the model optional contains a model. This means that the model could be loaded in general, but that there are issues with the model like incorrect value types, missing references, etc.
The Model itself provides methods for accessing every aspect of a model.
const rexsapi::TModel model = loadModel();
for (const auto& relation : model.getRelations()) {
for (const auto& ref : relation.getReferences()) {
for (const auto& comp : ref.getComponents()) {
std::cout << comp.getType() << "\n";
for (const auto& att : comp.getAttributes()) {
std::cout << "\t" << att.getAttributeId() << "\n";
}
}
}
}
Alternatively, if the model shall be processed in a complete way, the TModelVisitor
class can be used. It allows access to the complete model without the need for explicit iteration. Check the ModelVisitorTest
test and the model_dumper
tool for examples.
The most reliable way to create a REXS model is to use the TModelBuilder
class. It can create every aspect of a model, be it components, relations, or load spectrum, of a REXS model and highly abstracts the construction of REXS standard compliant models. The TModelBuilder
needs a specific REXS database model for checking and validating the model. Most model builder methods return a reference to the model builder in order to allow chaining of method calls resulting in dense easy to read code.
const auto registry = rexsapi::createModelRegistry("/path/to/rexs/database/models");
const auto& databaseModel = registry.getModel(rexsapi::TRexsVersion{"1.4"}, "en");
rexsapi::TModelBuilder modelBuilder{databaseModel};
modelBuilder.addComponent("concept_bearing", "bearing-id").name("Bearing No. 1");
modelBuilder.addAttribute("axial_force_absorption").value("negative");
modelBuilder.addAttribute("support_vector").unit("mm").value(
rexsapi::TFloatArrayType{70.0, 0.0, 0.0}).coded();
modelBuilder.addComponent("gear_casing", "gear-casing-id");
... [more attributes and components]
modelBuilder.addRelation(rexsapi::TRelationType::SIDE)
.addRef(rexsapi::TRelationRole::ASSEMBLY, "bearing-id")
.addRef(rexsapi::TRelationRole::INNER_PART, "gear-casing-id");
.addRef(rexsapi::TRelationRole::OUTER_PART, "shaft-id");
... [more relations]
auto model = modelBuilder.build("REXSApi Model Builder", "1.2", "en");
First you add components and attributes to the model. The last added component or attribute are the so called active component or attribute. All following method calls always affect the currently active component or attribute. The same is true for relations. Attributes need real C++ types as values.
If all necessary components have been added, you can start to add relations that reference these components via unique string ids. Alternatively, you can also use automatically generated ids that can be retrieved from the model builder after adding a component. You have to specify the correct roles for a specific relation type. The model builder will check all components, attributes, and relations against the chosen REXS database model version and will throw exceptions on any error in order to guarantee the construction of a standard compliant model.
Saving a REXS model to a file is straight forward using the TModelSaver
convenience class.
const rexsapi::TModel model = createModel();
rexsapi::TResult result;
rexsapi::TModelSaver{}.store(result, model, "/path/to/your/rexs/model/file",
rexsapi::TSaveType::XML);
if (result) {
std::cout << "sucessfully stored REXS model\n";
} else {
std::cerr << "failed to store REXS model\n";
}
The TModelSaver
class can store REXS models as xml or json. If successful, the result will convert to true and the model is stored. In case of a failure, the result will contain a collection of messages describing the issues. The file path to store the model to does not need any extension, the TModelSaver
will assign the correct extension automatically.
The library comes packaged with three tools: model_converter
, model_checker
, and model_dumper
. The tools can come in handy when working with rexs model files and can also serve as examples how to use the library.
The model_checker
checks files for compatibility with the REXSapi library. You can check complete directories with one go. The library expects REXS model files to be conformant to the REXS specification. However, the library supports a so called relaxed mode where most errors to the specfication are turned into warnings in order to process files even if they are not 100% compliant to the specifcation. The tool will print the found issues to the console. You can use the tools output to fix problems in the files.
Option | Description |
---|---|
--help, -h | Show usage and options |
--mode-strict | This is the default mode. Files will be checked to comply strictly to the standard. |
--mode-relaxed | This mode will relax the checking and produce warnings instead of errors for non-standard constructs. |
--warnings, -w | Enables the printing of warnings to the console. Otherwise, only errors will be printed. |
-r | If directories are specified as arguments, recurse into sub-directories. |
-m | Custom file extension mapping of the form ".rexs.in:xml". Will load files with the extension ".rexs.in" as xml files. Can be specified multiple times, but has to precede some other option or be terminated with --. |
--database, -d | The path to the model database files including the schemas (json and xml). |
Files and directories to look for model files to process. |
> ./model_checker --mode-relaxed -d ../models -m .rexs.in:xml -- FVA-Industriegetriebe_2stufig_1-4.rexs
File ".FVA-Industriegetriebe_2stufig_1-4.rexs" processed with 10 warnings
The model_converter
can convert REXS model files between xml and json format. Files can be converted in any direction, even into the same format. You can convert complete directories with one go. As with the model_checker
, the tool supports a relaxed mode for loading non-standard complying model files. If files do not conform to the standard, converting them may result in removed elements.
Option | Description |
---|---|
--help, -h | Show usage and options |
--mode-strict | This is the default mode. Files will be checked to comply strictly to the standard. |
--mode-relaxed | This mode will relax the checking and produce warnings instead of errors for non-standard constructs. |
--format, -f | The output format of the tool. Either json or xml. |
-r | If directories are specified as arguments, recurse into sub-directories. |
-m | Custom file extension mapping of the form ".rexs.in:xml". Will load files with the extension ".rexs.in" as xml files. Can be specified multiple times, but has to precede some other option or be terminated with --. |
--output, -o | The output path to write converted file to. |
--database, -d | The path to the model database files including the schemas (json and xml). |
Files and directories to look for model files to process. |
> ./model_converter --mode-relaxed -f json -d ../models -m .rexs.in:xml --output /out FVA-Industriegetriebe_2stufig_1-4.rexs
Converted FVA-Industriegetriebe_2stufig_1-4.rexs to /out/FVA-Industriegetriebe_2stufig_1-4.rexsj
The model_dumper
prints the loaded model to the console. As with the model_checker
, the tool supports a relaxed mode for loading non-standard complying model files. The tool can be used to check if the specific model can be loaded with the REXSapi correctly.
Option | Description |
---|---|
--help, -h | Show usage and options |
--mode-strict | This is the default mode. Files will be checked to comply strictly to the standard. |
--mode-relaxed | This mode will relax the checking and produce warnings instead of errors for non-standard constructs. |
-m | Custom file extension mapping of the form ".rexs.in:xml". Will load files with the extension ".rexs.in" as xml files. Can be specified multiple times, but has to precede some other option or be terminated with --. |
-s | Show some statistics of the model |
--attributes, -a | Show the component attributes |
--database, -d | The path to the model database files including the schemas (json and xml). |
The REXS model file to dump. |
> ./model_dumper --mode-relaxed -d ../models FVA-Industriegetriebe_2stufig_1-4.rexs
File "/Users/lfuerste/Development/REXSapi/test/example_models/FVA-Industriegetriebe_2stufig_1-4.rexs"
ApplId: 'Bearinx' ApplVer: 12.0.9241 (sandbox development) Date: 2022-04-21T11:42:31+01:00 REXSVer: 1.4
Relations
...
See CHANGELOG.md for detailed changelog information.
The library is header only and can be easily integrated into existing projects. Using CMake is the recommended way to use the library. However, the library also comes as a zip package which can be used without CMake. You have to set the C++ standard of your project to C++17 in order to build with the library.
The library has dependencies to other open source software. This dependencies will be either automatically downloaded by CMake or are prepackaged in the zip package. You can also use your own versions of the thirdparty libraries, but make sure the versions are compatible to the versions used by the REXSapi.
Just clone the git repository and add REXSapi as a sub directory in an appropriate CMakeLists.txt file. Then use the provided rexsapi interface as library. If you want to build with the examples, tools or the tests, you can set BUILD_WITH_EXAMPLES
, BUILD_WITH_TESTS
, and/or BUILD_WITH_TOOLS
to ON
.
set(CMAKE_CXX_STANDARD 17)
add_executable(test
main.cxx
)
set(BUILD_WITH_EXAMPLES ON)
add_subdirectory(REXSapi)
target_link_libraries(test PRIVATE rexsapi)
Alternatively, you can use CMakes FetchContent module to download REXSapi and make the projects interface available.
include(FetchContent)
FetchContent_Declare(
rexsapi
GIT_REPOSITORY https://github.com/fva-net/rexs-api-cpp.git
GIT_TAG origin/v1.1.0
)
FetchContent_MakeAvailable(rexsapi)
If you do not want to use CMake, you can download a REXSapi zip package. The package contains all necessary header files, including all dependencies. In order to build a REXSapi project, unzip the archive and add the resulting directories include
and deps/include
directory as additional header search directories to your build.
The library is header only. A build is only necessary if you want to run the tests or build the examples or tools.
- You will need the following software packages
- g++ 11.4.0 or higher
- clang 15.0.7 or higher
- cmake 3.22 or higher
- To install the dependencies on ubuntu
- Call
sudo apt-get install cmake g++
- Call
- Create a build directory in the source directory of REXSapi and change to it
- Call
cmake -DCMAKE_BUILD_TYPE=Release ..
- Call
cmake --build . --config Release
- To run the tests
- Call
ctest -VV -C Release
- Call
- You will need the following software packages
- Visual Studio 2022 or higher
- CMake support is build into Visual Studio 2022
- Open the local folder of the REXSapi project
- Visual Studio will configure the project automatically
- You will need the following software packages
- XCode 12.4 or higher
- cmake 3.22 or higher
- To install cmake on Mac
- Call
brew install cmake
- Call
- Create a build directory in the source directory of REXSapi and change to it
- Call
cmake -GXcode -DCMAKE_BUILD_TYPE=Release ..
- Call
cmake --build . --config Release
- To run the tests
- Call
ctest -VV -C Release
- Call
REXSapi uses the following thirdparty open source software
- cli11 2.4.1
- date 3.0.1
- doctest 2.4.10
- fmt 10.2.1
- nlohmann json 3.11.2
- miniz 3.0.2
- pugixml 1.14
- valijson 1.0.2
REXsapi is licensed under the Apache-2.0 license.
See the LICENSE file for more information.