[xsd-users] Partial update of in-memory structures & network transfer.

Moss, David R (SELEX Comms) (UK Christchurch) david.r.moss at selex-comm.com
Thu May 11 08:19:52 EDT 2006


All,

I'm looking for a generic way to update an in-memory structure given a
(possibly very nested) sub-element of that structure. This update will
be in the form of a byte array off the network (or from another file).
The updates can be requests to add, remove and update elements /
attributes and their content (where the schema permits it). 

Given the following schema (forgive the example but I couldn't cope with
abstract 'item1, item2..sub-item_a' etc scenarios!):

<?xml version="1.0" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

   <xsd:element name="car" type="car_t" />

   <xsd:complexType name="car_t">
      <xsd:sequence>
         <xsd:element name="engine" type="engine_t" />
         <xsd:element name="chassis" type="chassis_t" />
      </xsd:sequence>
   </xsd:complexType>

   <xsd:complexType name="engine_t">
      <xsd:sequence>
         <xsd:element name="oil" type="xsd:integer" />
      </xsd:sequence>
   </xsd:complexType>

   <xsd:complexType name="chassis_t">
      <xsd:sequence>
         <xsd:element name="wheel" type="wheel_t" minOccurs="2"
maxOccurs="6" />
         <xsd:element name="exhaust" type="xsd:integer" />
      </xsd:sequence>
   </xsd:complexType>

   <xsd:complexType name="wheel_t">
      <xsd:sequence>
         <xsd:element name="tyre" type="xsd:integer" />
         <xsd:element name="pressure" type="xsd:integer" />
         <xsd:element name="rim" type="xsd:integer" />
      </xsd:sequence>
      <xsd:attribute name="id" type="xsd:integer" />
   </xsd:complexType>

</xsd:schema>

there could be a point at runtime where the in-memory model contains the
following data: 

<car>
   <engine>
      <oil>5</oil>
   </engine>

   <chassis>
      <wheel id="1">
         <tyre>1</tyre>
         <pressure>1</pressure>
         <rim>1</rim>
      </wheel>
      <wheel id="2">
         <tyre>2</tyre>
         <pressure>2</pressure>
         <rim>2</rim>
      </wheel>
      <exhaust>5</exhaust>
   </chassis>
</car>


Some data comes from the network that represents a new wheel (as the
schema will be big, the entire document won't be retransmitted every
time, plus this gives the flexibility of allowing different clients to
manage different areas of the schema e.g. the chassis dept. doesn't need
to know about the engine dept - they just know they exist as part of a
car) :

<car>
   <chassis>
      <wheel id="3">
         <tyre>3</tyre>
         <pressure>3</pressure>
         <rim>3</rim>
      </wheel>
   </chassis>
</car>

Obviously this fragment isn't valid against the schema but it is
constructible (as xsd allows invalid (against schema) objects using the
--generate-default-ctor command).

The first issue here is how to stream data to and from xsd objects - is
your planned work to allow serialisation to (and from?!) compact binary
formats for over-the-wire transfer something that would be able to
address this? It would be nice if something like this could be done:

// Get the data from the network
BYTE* pCarFragment =...

// Put the fragment into an xsd object - the main car object knows where
a wheel lives.
car_t car;
pCarFragment >> car;	// operator of choice, or +=, member Add( type&
) etc...


Next, given that it will be possible to do something like that, it would
be possible to build / update some master data record from separate
sources:

car_t masterCar =...

car_t wheelFragment = ...
car_t chassisFragment = ...

masterCar += wheelFragment;
masterCar += chassisFragment;

This would also mean the different parts of the instance document could
live in physically separate files 
e.g. engine.xml 

<car>
   <engine>
      <oil>5</oil>
   </engine>
</car>

and chassis.xml. 

<car>
   <chassis>
      <wheel id="1">
         <tyre>1</tyre>
         <pressure>1</pressure>
         <rim>1</rim>
      </wheel>
      <wheel id="2">
         <tyre>2</tyre>
         <pressure>2</pressure>
         <rim>2</rim>
      </wheel>
      <exhaust>5</exhaust>
   </chassis>
</car>

and be combined into one object when loaded.


A mechanism to allow data to be removed or updated would also be
required:

Change the tyre pressure:
<car>
   <chassis>
      <wheel id="2">
         <pressure>99</pressure>
      </wheel>
   </chassis>
</car>

car_t pressureChange = ...

car_t masterCar = ...

masterCar.Update( pressureChange );	

Instead or as well as member functions, operators could be overloaded;
maybe ~= or *= for Update()? To remove some data, the member function
Remove(...) or operator -=  could be used.


The Add / Remove / Update operations could return failure (or throw an
exception) if the operation was invalid against the schema e.g. adding /
updating something to an out of range value or trying to remove a
mandatory element.


When the in-memory validation is available it would also be possible to
do

bool isValid = masterCar.valid(); 	

to check that the overall content was correct against the schema (I seem
to remember reading something to this effect on this forum!). 


I realise this is quite a philosophical email and there probably aren't
any solid answers ( other than "what?!"  :-) ), but it's something to
think about...


Cheers,
Dave.


Dave Moss
SELEX Communications
Grange Road
Christchurch 
Dorset  BH23 4JE
United Kingdom
Tel: + 44 (0) 1202 404841
Email: david.r.moss at selex-comm.com


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://codesynthesis.com/pipermail/xsd-users/attachments/20060511/17642116/attachment.html


More information about the xsd-users mailing list