getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
901 stars 76 forks source link

XML support using libxml2 or pugixml #21

Closed liuzicheng1987 closed 8 months ago

liuzicheng1987 commented 8 months ago

The library could use XML support by interfacing libxml2 or pugixml (https://github.com/zeux/pugixml). There aren't many good reflection based XML parsers out there for and XML is still relevant in some domains, so there is high pay-off here. On the other hand, interfacing XML is a bit more difficult than most other formats just because of how it is designed.

Generally speaking, another format can be integrated by implementing the IsReader and IsWriter concepts, which are documented here: https://github.com/getml/reflect-cpp/blob/main/docs/supporting_your_own_format.md

There are a couple of things to keep in mind for XML in particular that you do not have to deal with when it comes to most other formats:

  1. Unlike most other formats, XML objects require names. This can be accomplished either by extracting the type by combining get_type_name (https://github.com/getml/reflect-cpp/blob/main/include/rfl/internal/get_type_name.hpp) and remove_namespaces (https://github.com/getml/reflect-cpp/blob/main/include/rfl/internal/remove_namespaces.hpp). Alternatively, the user can define a literal Name on the struct. If the user defines a Name on the struct, that should take precedence. The equivalent should be the Tag in TaggedUnion which works exactly the same way (https://github.com/getml/reflect-cpp/blob/main/docs/variants_and_tagged_unions.md).

  2. Behaviour should be equivalent to https://pydantic-xml.readthedocs.io/en/stable/pages/quickstart.html

To implement the requirements laid out in 2. it is probably necessary to have a custom implementation for rfl::parsing::Parser<XMLReader, XMLWriter, NamedTuple>. (For most other formats, you wouldn't have to do that.)

liuzicheng1987 commented 8 months ago

You should implement tests for this, in the same way the tests are set up for flexbuffers - by providing a Dockerfile that contains a reproducible environment in which the tests can be compiled and run:

https://github.com/getml/reflect-cpp/tree/main/tests/flexbuffers