Serializing an arbitrary shape to XML

Jan 2, 2013 at 9:53 PM

I need to serialize an arbitrary shape to XML - but not using the default XML format suggested by NShape "out of the box". I understand that your default Repository Writer does not use .NET serialization - instead it uses IEntity.SaveFields() method in conjunction with the GetPropertyDefinitions() method. So it's not so easy to solve my task - that's why I'm asking for some help.

To make it clear what exactly I need to do, let's take the "Dataweb.NShape.GeneralShapes.Text" shape as an example. This shape does not have its own SaveFields() method implementation, so the fields to be saved are determined from the base types this shape inherits from:

+---------------------------+------------------------------------------------------+
| Shape type                | Fields saved by SaveFields() method                  |
+---------------------------+------------------------------------------------------+
| Shape                     | (none)                                               |
|   ShapeBase               | template, modelObject, X, Y, ZOrder, Layers,         |
|                           |   SecurityDomainName, privateLineStyle               |
|     PathBasedPlanarShape  | Angle, privateFillStyle                              |
|       CaptionedShapeBase  | privateCharacterStyle, privateParagraphStyle, Text   |
|         RectangleBase     | Width, Height                                        |
|           TextBase        | AutoSize                                             |
|             Text          | (none)                                               |
+---------------------------+------------------------------------------------------+

So "Text" shape has totally 16 fields to be saved, and 4 of them are "styles". We know the following about these styles:

+---------------------------+------------------------------------------------------+
| Style type                | Fields saved by SaveFields() method                  |
+---------------------------+------------------------------------------------------+
| Style                     | name, title                                          |
|   LineStyle               | lineWidth, dashStyle, dashCap, lineJoin, colorStyle  |
|   ColorStyle              | color, transparency, convertToGray                   |
|   FillStyle               | baseColorStyle, additionalColorStyle, fillMode,      |
|                           |   fillPattern, convertToGrayScale, <image stuff>     |
|   CharacterStyle          | fontFamily.Name, fontSizeInPoints, fontStyle,        |
|                           |   colorStyle                                         |
|   ParagraphStyle          | alignment, trimming, padding.Left, padding.Top,      |
|                           |   padding.Right, padding.Bottom, wordWrap            |
+---------------------------+------------------------------------------------------+

What I need - is a "magic" method SaveShapeToXml(Shape shape, XmlDocument xDoc) which will produce xDoc with the following body (some nodes are omitted to make it shorter):

<ShapeInfo>
  <template>
    <!-- I need never save it -->
  </template>
  <modelObject>
    <!-- I need never save it -->
  </modelObject>
  <X>100</X>
  <Y>200</Y>
  <ZOrder>10</ZOrder>
  <Layers>
    <!-- I need never save it -->
  </Layers>
  <SecurityDomainName>
    <!-- I need never save it -->
  </SecurityDomainName>
  <privateLineStyle>
    <name>BlackDash2</name>
    <title>Black Dash 2pt</title>
    <lineWidth>2</lineWidth>
    <dashStyle>Dash</dashStyle>
    <dashCap>Triangle</dashCap>
    <lineJoin>Round</lineJoin>
    <colorStyle>
      <!-- omitted -->
    </colorStyle>
  </privateLineStyle>
  <Angle>0</Angle>
  <privateFillStyle>
    <!-- omitted -->
  </privateFillStyle>
  <privateCharacterStyle>
    <fontFamilyName>Arial</fontFamilyName>
    <fontSizeInPoints>12</fontSizeInPoints>
    <fontStyle>Bold</fontStyle>
    <colorStyle>
      <!-- omitted -->
    </colorStyle>
  </privateCharacterStyle>
  <privateParagraphStyle>
    <!-- omitted -->
  </privateParagraphStyle>
  <Text>Hello, world!</Text>
  <Width>300</Width>
  <Height>120</Height>
  <AutoSize>true</AutoSize>
</ShapeInfo>

My question: is it possible to create this kind of method? maybe some custom RepositoryWriter?!

PS: please note that I need a possibility to suppress saving of certain fields (e.g. "Layers", "SecurityDomainName" etc).

Coordinator
Jan 15, 2013 at 11:14 AM

Hello Commance,

Comanche wrote:
My question:
is it possible to create this kind of method? maybe some custom RepositoryWriter?!
PS:
please note that I need a possibility to suppress saving of certain fields (e.g. "Layers", "SecurityDomainName" etc).

a custom Store implementation with RepositoryWriter/RepositoryReader would be a possible (and "NShape"-like) solution.
The store class is used for saving data to media, e.g. to XML or to a database. It is responsible for calling the rather atomic Reader/Writer methods and therefore can also skip certain properties.
The store can be used with all repository components. You can even change stores at runtime (as long as they use the same type of shape Id).

Another approach would be to write some kind of storage wrapper like the ***ShapeInfo facade classes you mentioned in the other post. Implement the IEntity interface and pass the shape to store to constructor. As you implement the IEntity interface, you can skip certain properties by implementing your own SaveFields / SaveInnerObjects methods which are called by the repository.

Jan 17, 2013 at 8:17 AM

Thank you for your feedback!

I'll try the 2nd approach (it seems more clear to me). No doubts I'll post again with additional questions! :)