[xsd-users] Polymorphism, am I doing something wrong?

Rob Ursem Rob.Ursem at cmgl.ca
Fri May 2 12:32:28 EDT 2014


Boris, 

I have put the plain text below, hopefully that cleans things up.

I am having trouble getting the derived_cast to work since the generated code does not provide a pointer variable to me. I have made the data members public so I could use the "detach()" method on the one<T> class, which provides me an auto_ptr but that is not a generic method.

Alternatively I can write some perl to generate custom classes that provide me the pointers that I need but I was hoping for a more structural method since the deserialization seems to do the right thing (as I can see in the debugger).

ORIGINAL MESSAGE: =======================================================

I've been looking at the polymorphism example and see how that works, but I can't seem to make my example work.

Consider the following schema:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:complexType name="cs_abstractArrayOfPoints3d" abstract="true">
		<xs:sequence/>
	</xs:complexType>
	<xs:complexType name="cs_pointGeometryPatch">
		<xs:sequence>
			<xs:element name="points" type="cs_abstractArrayOfPoints3d" minOccurs="1" maxOccurs="1"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="cs_arrayOfExplicitPoints3d">
		<xs:complexContent>
			<xs:extension base="cs_abstractArrayOfPoints3d">
				<xs:sequence>
					<xs:element name="coordinates" type="xs:integer" minOccurs="1" maxOccurs="1"/>
				</xs:sequence>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xsd:element name="PointGeometryPatch" type="cs_pointGeometryPatch"/>
</xsd:schema>

In this schema we define a "cs_pointGeometryPatch" type that has an element named "points" of type "cs_abstractArrayOfPoints3d". This type is an abstract type and for the sake of the example, there is only one 'implementation' of this abstract class in the schema.

An example xml for this schema is:

<?xml version="1.0"?>
<PointGeometryPatch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="points.xsd">
	<points xsi:type="cs_arrayOfExplicitPoints3d">
		<coordinates>3</coordinates>
	</points>
</PointGeometryPatch>

In this case a non-abstract class is used for the points element. This class is derived from "cs_abstractArrayOfPoints3d" so all is well.

The generated code (only hxx shown) is:
class cs_pointGeometryPatch: public ::xml_schema::type
{
  public:
  // points
  // 
  typedef ::cs_abstractArrayOfPoints3d points_type;
  typedef ::xsd::cxx::tree::traits< points_type, char > points_traits;

  const points_type&
  points () const;

  points_type&
  points ();

  void
  points (const points_type& x);

  void
  points (::std::auto_ptr< points_type > p);

  // Constructors.
  //
  cs_pointGeometryPatch (const points_type&);

  cs_pointGeometryPatch (const ::xercesc::DOMElement& e,
                         ::xml_schema::flags f = 0,
                         ::xml_schema::container* c = 0);

  cs_pointGeometryPatch (const cs_pointGeometryPatch& x,
                         ::xml_schema::flags f = 0,
                         ::xml_schema::container* c = 0);

  virtual cs_pointGeometryPatch*
  _clone (::xml_schema::flags f = 0,
          ::xml_schema::container* c = 0) const;

  virtual 
  ~cs_pointGeometryPatch ();

  // Implementation.
  //
  protected:
  void
  parse (::xsd::cxx::xml::dom::parser< char >&,
         ::xml_schema::flags);

  protected:
  ::xsd::cxx::tree::one< points_type > points_;
};

We can see that when we request "points()" from a cs_pointGeometryPatch class, we get a reference to points_type, which is the abstract datatype. I see that when I parse the given xml with the schema, the parser instantiates an instance of "cs_arrayOfExplicitPoints3d" but due to the fact that the accessor for points is a reference and not a pointer, there is no way for me to typecast the abstract type to a derived type. I thus see no way to programmatically get to the value 3 (for coordinates) in the above shown xml. 

Am I missing something?


________________________________________
From: Boris Kolpackov [boris at codesynthesis.com]
Sent: Friday, May 02, 2014 9:58 AM
To: Rob Ursem
Cc: xsd-users at codesynthesis.com
Subject: Re: [xsd-users] Polymorphism, am I doing something wrong?

Hi Rob,

Rob Ursem <Rob.Ursem at cmgl.ca> writes:

>    Consider the following schema:

For some reason your emails come really garbled up. I can barely
decipher what's going on. Could you try to send thing in plain
text next time.

>    Am I missing something?

If I managed to understand your question, you are not clear on how
to discover what the concrete (derived) type of the instance is
and how to get hold of it. If that's the case, then what you use
is dynamic_cast to discover and get the concrete type at runtime.
Section 2.11, "Mapping for xsi:type and Substitution Groups" in
the C++/Tree Mapping User Manual shows how to do this:

http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.11

Boris



More information about the xsd-users mailing list