2

Suppose I have a structure in C or C++, such as:

struct ConfigurableElement {
   int ID;
   char* strName;
   long prop1;
   long prop2;
   ...
};

I would like to load/save it to/from the following XML element:

 <ConfigurableElement ID="1" strName="namedElem" prop1="2" prop2="3" ... />

Such a mapping can be trivially done in Java/C# or any other language with run-time reflection for the matter. Can it be done in any non-tedious way in C++ with macros/template trickery?

Bonus points for handling nested structures/unions.

2 Answers 2

3

The technique you want is called serialization. You may want to read these articles:

http://www.codeproject.com/KB/cpp/xmlserialization.aspx

http://www.codesynthesis.com/products/xsd/ <=== Very close to what you want!

http://www.artima.com/cppsource/xml_data_binding.html

http://www.ibm.com/developerworks/xml/library/x-serial.html

http://www.firstobject.com/xml-serialization-in-c++.htm

EDIT:

There is another option for you: Xmlize provided by Ultimatepp:

http://www.ultimatepp.org/reference$Xmlize.html

http://www.ultimatepp.org/reference$Xmlize$en-us.html

http://www.ultimatepp.org/reference$XmlizeCustomValue$en-us.html

http://www.ultimatepp.org/reference$Xmlize_std$en-us.html

http://www.ultimatepp.org/reference$XML$en-us.html

Sign up to request clarification or add additional context in comments.

3 Comments

I know what serialization is. I am interested in human-readable serialization in the exact format specified. But the XSD one might actually be interesting.
Yes, I predicted that XSD is very close to what you want. It's dual-licensed, GPL & commercial licensed.
3

Tips and tricks always exists. Take a look at Metaresc library https://github.com/alexanderchuranov/Metaresc

It provides interface for types declaration that will also generate meta-data for the type. Based on meta-data you can easily serialize/deserialize objects of any complexity. Out of the box you can serialize/deserialize XML, JSON, YAML, XDR, Lisp-like notation, C-init notation.

Here is a simple example:

#include <stdio.h>
#include <stdlib.h>

#include "metaresc.h"

TYPEDEF_STRUCT (host_t,
                (char *, host),
                int port,
                );

TYPEDEF_STRUCT (config_t,
                (host_t, local),
                (host_t, remote),
                (char *, name),
                );

int main (int argc, char * argv[])
{
  config_t config = {
    .local = {
      .host = "localhost",
      .port = 8080,
    },
    .remote = {
      .host = "google.com",
      .port = 80,
    },
    .name = "service",
  };

  char * str = MR_SAVE_XML (config_t, &config);
  if (str)
    {
      printf ("%s\n", str);
      free (str);
    }
  return (EXIT_SUCCESS);
}

This program will output

$ ./config
<?xml version="1.0"?>
<config>
  <local>
    <host>localhost</host>
    <port>8080</port>
  </local>
  <remote>
    <host>google.com</host>
    <port>80</port>
  </remote>
  <name>service</name>
</config>

Library works fine for latest gcc and clang.

2 Comments

I'm a newbie. How to use this library with code::blocks under Windows 7 ? I have tried to add .c and .h files but when I include metaresc.h and build it in my project, the file mr_pp.h can't be found. Where can I find this file, I don't see it in the project. Thanks
mr_pp.h is auto generated header file. You could build it only using autoconf/automake/make toolchain. More details could be found here github.com/alexanderchuranov/Metaresc/blob/master/README You can't just put header files into your project. You need to build library separately and link with main project on linkage stage. See examples/ subfolder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.