[xsd-users] how to make arbitrary element insertions in a "mixed" sequence of elements where the CodeSynthesis data model does not adequately describe the ordering of elements

Wheeler, Bill NPO bill.npo.wheeler at intel.com
Mon Nov 8 16:07:30 EST 2010


Boris,

   Never mind my last question as I think I understand the better approach now...the trick is to override the "parse" and "operator<<" in the class *containing* the order-dependent elements.  Things get much cleaner and straight forward then.

   I now have a much simpler question.  If I have a derived class, C_container (with auto-generated base class C_container_base) with the following constructor:

C_container::C_container (const xercesc::DOMElement& e,
             		::xml_schema::flags f,
				::xml_schema::container* c) : C_container_base( e, f, c )
{
  if ((f & ::xml_schema::flags::base) == 0)
  {
    ::xsd::cxx::xml::dom::parser< char > p (e, true, false);
    this->parse (p, f);
  }
}

When this calls into the C_container_base version of the constructor, I want the value of "f" to be such that it does not invoke the base class version of the parse method, because I will customize the parse function in the C_container class.  From the definition of ::xml_schema::flags, it is not clear to me what value of "f" I should use to inhibit the base class parse method.  What value would you suggest?

Thanks
  


-----Original Message-----
From: Wheeler, Bill NPO 
Sent: Monday, November 08, 2010 11:51 AM
To: 'Boris Kolpackov'
Cc: xsd-users at codesynthesis.com
Subject: RE: [xsd-users] how to make arbitrary element insertions in a "mixed" sequence of elements where the CodeSynthesis data model does not adequately describe the ordering of elements

Boris,

   Thanks for your response.  After reading thru the material, I can appreciate how type customization acts as a low-level tool for me to override parsing and serialization functions to handle my arbitrary insertion of different element types into a list such that the order of these elements is important and maintainable.  However, I wanted to validate with you what the overall implementation approach would be as the cited examples stop short of describing this and I don't fully understand the underlying implementation of your design.  Here's my idea of what this might look like:

	1) After reading/parsing an XML file, traverse across the A_elem and B_elem datamodel lists.  For each element, find the underlying DOM node and infer its node position on the child list of the parent DOM node.  Then place the A_elem (or B_elem) element on a "common order list" to reflect the overall ordering.
	2) When I choose to insert new A or B elements at arbitrary positions in the order, insert them onto this common order list, to describe their relative position.
	3) At serialization time, using my own overridden "operator<<" function, wait until the last serialization call has been made for all the A and B elems.  When that final serialization call is made, all the DOM nodes are now known and can then be re-ordered based on the common order list.


Is this approach valid, or is there a better way?

Thanks,

Bill



-----Original Message-----
From: Boris Kolpackov [mailto:boris at codesynthesis.com] 
Sent: Monday, November 08, 2010 10:00 AM
To: Wheeler, Bill NPO
Cc: xsd-users at codesynthesis.com
Subject: Re: [xsd-users] how to make arbitrary element insertions in a "mixed" sequence of elements where the CodeSynthesis data model does not adequately describe the ordering of elements

Wheeler, Bill NPO <bill.npo.wheeler at intel.com> writes:

> I have a schema (which I cannot modify) that has the property where 2 types of elements can be inter-mingled arbitrarily.  To be more specific, the following stripped down schema describes the situation I have:
> 
> <?xml version="1.0" ?>
> 
> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
> 
>   <xsd:complexType name="A_elem">
>     <xsd:sequence>
>       <xsd:element name="some_data" type="xsd:int"></xsd:element>
>     </xsd:sequence>
>   </xsd:complexType>
> 
>   <xsd:complexType name="B_elem">
>     <xsd:sequence>
>       <xsd:element name="some_other_data" type="xsd:boolean"></xsd:element>
>     </xsd:sequence>
>   </xsd:complexType>
> 
>   <xsd:group name="X_group_elems">
>     <xsd:choice>
>       <xsd:element name="A" type="A_elem" />
>       <xsd:element name="B" type="B_elem" />
>     </xsd:choice>
>   </xsd:group>
> 
>   <xsd:complexType name="X_root">
>     <xsd:sequence>
>       <xsd:group ref="X_group_elems" minOccurs="0" maxOccurs="unbounded" />
>     </xsd:sequence>
>   </xsd:complexType>
> 
>   <xsd:element name="ROOT" type="X_root"></xsd:element>
> </xsd:schema>
> 
> 
> I think this falls under the category of a "mixed content" model whereby 
> the CodeSynthesis data model does not reflect the actual ordering of 
> elements.  That is, the X_root object will have an A list and B list 
> of elements, but not a list that reflects the inter-mingled list of 
> A/B elements.  

This is not really a mixed content model. The issue here is with the
way C++/Tree represents the content model. To keep the API simple,
C++/Tree "flattens" the content which, in some cases, can lead to 
loss of the order information. The following thread discusses this
problem in detail and lists all the available solutions:

http://www.codesynthesis.com/pipermail/xsd-users/2010-March/002741.html


> Say I want to insert a new <B> elem just before the <B> elem (and just 
> after the 2nd <A> elem).  Could I simply create a new B elem and do a 
> "push_back" onto the B elem list of the X_root object.  Then find the 
> underlying DOM node for that new B elem, remove it from its parent node 
> and then re-insert it as a child node of the same parent node in the 
> correct position. Would this work?  

Unfortunately, this won't work. When you programmatically create a node
in the object model, the underlying DOM nodes are not created. For this
to work you would need to manually create the DOM node (which can be
done using the serialization operator), then associate it with the
object model node, and, finally, insert it in the right position in
the DOM document. This can be done. It is just a lot of work. Type
customization will be a simpler solution.

Boris



More information about the xsd-users mailing list