3

We’ve got a huge data object structure, containing a lot of properties that are actually arrays. Now, we need to stream the data to an XML document.

For that, we thought to use the NativeXML component to stream. It uses the same mechanism that’s also used for TComponent streaming. This works fairly nicely, except that it doesn’t stream the indexed properties.

Is there a way to do this anyway, or are there components that are capable of doing this?

Martijn
  • 13,225
  • 3
  • 48
  • 58
  • 1
    Even my XML Serialization engine does not support index properties. http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas – Robert Love Feb 08 '11 at 16:59
  • @RobertLove: Does it support arrays, though? – Martijn Feb 08 '11 at 17:01
  • It should, but I have to be honest I did not test that functionality. – Robert Love Feb 08 '11 at 17:05
  • I suggest http://www.omnixml.com/ it's very good, I can't recall if it can handle simple array types, but that shouldn't be too hard to implement yourself using collections... –  Feb 08 '11 at 20:06
  • 1
    Why would you want to serialize indexed properties? A property does not hold any data. It does either access a field or has a getter function that computes its values (again accessing some field). So IMHO all you have to think about is serializing the fields. – jpfollenius Feb 08 '11 at 21:57
  • see this answer: http://stackoverflow.com/questions/2491308/delphi-rtti-for-indexed-properties-in-2010 –  Feb 09 '11 at 01:25
  • @Smasher: The fields underlying the indexed properties are arrays. Do you know of a way to serialize those _automatically_? – Martijn Feb 09 '11 at 08:27
  • @Martijn: RTTI is available for arrays so this should be possible. However, my point was that the question should be about serializing arrays and not about indexed properties. – jpfollenius Feb 09 '11 at 09:44
  • Previously indexed properties could not be published in Delphi, so could not be serialized via RTTI. Is this possible now, with the extended RTTI? – Marek Jedliński Feb 09 '11 at 21:16
  • 2
    FYI - RTTI for array properties was added in XE2 :) – David Taylor Sep 20 '11 at 03:56

2 Answers2

3

Indexed properties are not exposed to RTTI (and still aren't in Delphi XE), and they are not streamed by TComponent either.

If you want to stay with the TComponent mechanism (or a pure RTTI-based streaming), one option is to use TCollection, which does get streamed "as an array". However that imposes severe constraints on your arrays, ie. their container has to be a subclass of TCollection, and their items have to be a subclass of TCollectionItem.

I don't know the NativeXML components, but if they are based on TWriter/TReader, another option could be to use DefineProperties, this allows you to define your own properties, and you can then stream whatever you wish, however you wish.
That involves special code for streaming, but you could place that code in class attributes if your arrays are not too specific, and handle everything in one of your root classes.

Eric Grange
  • 5,931
  • 1
  • 39
  • 61
  • `DefineProperties` would definitely be an option, thanks; I’d forgotten about that one. It’s a shame that turns the defined properties into a binary stream, though... Kinda defeats the purpose of XML. – Martijn Feb 16 '11 at 07:50
0

In the end, we resorted to creating a few extra classes (inheriting from TPersistent) for the storage of the array properties; it turned out there was only a limited set of array types. Delphi's indexed properties turned out to be really useful: we could just specify one getter function, and define most fixed elements of the array as separate properties referencing that one getter, and an index. Those properties now get serialized as proper XML elements, with the proper name as well.

Adding constructors and destructors to all classes using them took a few tedious hours, though.

Anyway, thanks for all the suggestions!

Martijn
  • 13,225
  • 3
  • 48
  • 58