Delphi Serialize Object To Xml

/ Comments off
Delphi Serialize Object To Xml 4,4/5 1230 reviews

What's a good way to serialize a Delphi object tree to XML-using RTTI and not custom code? I would have loved to find that this feature is already built into Delphi, but it doesn't seem to be. I've found a few components (posted, below) that seem like they might perform this function. What's a good way to serialize a Delphi object tree to XML-using RTTI and not custom code? I would have loved to find that this feature is already built into Delphi, but it doesn't seem to be.

5 Dec 2015CPOL
In the article I describe the possibilities of standard Delphi DFM-serialization mechanism. I start from the basics and then try to cover more complex situations.

Introduction

DFM-serialization mechanism which Delphi ships with may be pretty useful. Usually the basics of this mechanism are well-known by Delphi programmers. But there are real-world scenarios when you should go beyond the basics and the mechanism actually allows you to do that. In the article I will start from the basics and then try to cover more complex situations.

About DFM-format

DFM-format actually experienced some serious improvements over the history of Delphi. Historically it was binary and not readable. But we are talking about the current state of the format. The primary target of DFM-format was to store descriptions of the forms in order to make it simple to create form descriptions in design-time and create actual forms from descriptions in run-time. The big advantage of DFM-format is its native Delphi support (a little of coding is needed to implemet serialization support for Delphi object). The disadavntage of DFM-format is its low interoperability (when we need to integrate with some external systems it is more preferrable to use standard formats such as XML or JSON).

Object properties

Let's start from the simple example:

It is a description of the form, which was generated by VCL Forms application wizard. I just modified some properties of the form. As you can see DFM-format is pretty straightforward. The description starts with object name and class type and inside this block all object properties with their values are presented each on its own string and with block indent. Here we can see properties with integer, boolean, string and enumeration data types.

Child components

If I will add some components onto the form they will appear inside DFM-file as child objects for the form object. For example when I added TMemo and TPanel with TButton on it onto the form the DFM-file became to look like this:

Delphi serialize object to xml free

As you can see the whole object tree was saved into one single DFM-format file.

Custom classes serialization

In spite of the fact that DFM-serialization is primarily created to store form in the textual descriptions in design-time and to restore forms from those descriptions in run-time, it is actually pretty powerful serialization mechanism, which we can use in our projects for our own custom objects.

Custom class

I created sample application, which contains the following class declaration:

Sample application form

In the sample application there are two buttons, one of which converts this object into DFM representation and stores it in TMemo component of the form and another button converts this object back from DFM representation in TMemo Anime studio 8 free download. component into the object instance.

Streaming implemetation

The methods which access DFM streaming mechanism to perform actual object serialization and deserialization look like this:

So we can use DFM-streaming mechanism to store and restore our own classes. There are quite of limitations on the types of properties, which we can use in the published class section (and which are that's why stored in the DFM). It is forbidden or not supported to use properties of type pointer, record, array, interface and object (in the case when the object is not inherited from TPersistent). It is quite interesting that Variant properties streaming is supported, but it requires that Variant property should have value which in its turn can be streamed.

Unicode support

The previously mentioned sample application allows to research the behavior of serialization mechanism, when unicode characters are used. Delphi fully supports unicode now, but in the DFM-file unicode characters appear as a sequence of symbol codes. It is good news, that Delphi supports unicode in DFM-files, but unfortunately when unicode characters are used in the string values DFM-file representaions of these values becomes not readable. Actually when non-latin characters, which we want to use in the DFM-file, fall into default operating system codepage for non-unicode programs we can use these symbols in the DFM-string values and Delphi streaming system will recognize these symbols. But Delphi makes no assumptions over the default operating system codepage for non-unicode programs, so all non-latin characters in the DFM-file by default are encoded with symbol codes.

Postponed initialization

Serialize Object To Xml

Sometimes you need to perform some actions after deserialization from DFM is completed. For example, if you develop a visual component you likely want to suppress updating the component during the time of deserialization and likely want to update component when deserialization is completed. Besides, there may be some properties which work only together and that's why you need the component to be completely deserialized to use these properties properly.

To handle such situations gracefully TComponent class supports Loaded method, which you can override in your descendant class. And also TComponent supports ComponentState property, which contains csLoading flag when component is being loaded from stream. It allows you to check if ComponentState property contains csLoading flag to suppress some actions which you don't need until object is fully deserialized.

Custom properties

It is possible to gain full control over property serialization and deserialization. For this we need to define custom methods to store object property in DFM-file and restore object property from DFM-file. When we do it we actually can store any object type, but we need to represent it through available primitive types. Also when we do it we can read some property and not write it or write some property, which was not read. It may become useful when we have legacy object properties, which differ from actual object properties and we need to perform some conversion. Internally we will use TReader and TWriter methods, which are actually very flexible.

An example below shows the class, which uses custom property serialization mechanism:

The DFM-file with custom property will look like this:

Object tree serialization

In the previous example there was only one object, which was streamed. Actually it is rare situation: in real scenarios we usually have some object tree, which we want to store in DFM-format and later to restore from DFM-format. Delphi serialization mechanism supports several approaches, which allow to store a whole object tree in a single DFM-file. We will discuss these approaches now.

C# Serialize To Xml

Collections support

Delphi supports collections of objects, which can be serialized into DFM. The advantage of using collections is Delphi support for editing collections in design-time (you can use standard editor and property inspector to setup a collection). And another advantage is support for serialization with no coding involved. The drawback of collections is the need to inherit from predefined class and that all items in the collection must inherit from one single class type.

To define our own collection we need to create a descendant of TCollectionItem class and, may be, a descendant of TCollection class (actually for serialization support we need to inherit from TOwnedCollection class). Having done it we can make published object property with TCollection class. An example below shows minmal required code to implement a serializable collection with custom items class:

The result DFM will look like this:

You can use the attached sample application to experiment with collection serialization mechanism.

Subcomponents support

Sometimes a group of components exists as a whole. It means that all linked components are created and destroyed simultaneously. And sometimes we want some component to be the part of the other component and we want easily setup both components in design-time. For this scenario Delphi supports subcomponents mechanism. This mechanism allows for component to be stored between with all its subcomponents.

The following code shows simple example of subcomponent usage:

The result DFM-file looks like this:

You can use attached sample application to experiment with subcomponent serialization mechanism.

Child components support

Sometimes you need to store a whole object tree inside the DFM-file and the items in the tree can have different classes. In this scenario you cannot use Delphi collections and you need to create component tree. Delphi TComponent class supports child components list. When you create child component, you just need to specify its parent component as owner. This allows you to create component tree. But by default child components are not stored in the DFM-file and for such storing to happen you need to override some TComponent class methods (namely GetChildOwner and GetChildren). The desired behavior of storing child component descriptions inside the DFM-file is already implemented for TCustomForm class so in our own implementation we just need to do something similar.

An example below shows code of TComponent descendant class, which allows to store its child components inside DFM-file:

The result DFM-file looks like this:

You can use the attached sample application to experiment with object tree serialization mechanism.

Conclusions

In the article I tried to describe Delphi native serialization mechanism in depth (some topics are still not covered though). I hope that this will material help readers to understand that Delphi serialization mechanism is pretty useful and extendable. It is used mostly by component developers, but actually one can use it to store and restore any application object tree.

Active6 years, 4 months ago

Using Delphi XE:

XML data binding wizard generates Delphi class based on XML/XSD - works great.

BUT I also need to go the other way: Convert Delphi classes into XML. I don't find any support for that in XE. (I know this is quite simple to accomplish with C#, .NET, but obviously, since Delphi doesn't really support Reflection it's a lot more difficult than with C#)

One option I do have it is write the class in C# with SharpDevelop and use the MS utility (which I believe is a free download) to generate XML from the C# code. I also have VS 2005 that supports this, but it's not installed and I'd prefer not get to involved with it).

Anyone have a suggestion as to how to go about getting this done: Straight from Delphi to XML/XSD? An open source tool would be nice, or some good units that will do this.

Vector
VectorVector
4,5088 gold badges45 silver badges93 bronze badges

2 Answers

Robert Love wrote an article in late 2009 covering that topic: Xml Serialization - Basic Usage. It uses the 'new' RTTI available as of Delphi 2010.

Rob KennedyRob Kennedy
148k17 gold badges239 silver badges424 bronze badges

The NativeXml and OmniXML open source libraries can convert Delphi objects to XML (not XSD). They support object serialization and deserialization even with Delphi versions before 2010.

So it would be possible to use them in a first step to create a XML file, which then can be passed to the Data Binding Wizard for Delphi class code generation.

mjnmjn
26.5k24 gold badges145 silver badges324 bronze badges

Serialize Xml File

Not the answer you're looking for? Browse other questions tagged xmldelphixml-serializationdelphi-xexsd.exe or ask your own question.