[xsd-users] How to create an object from the xml data without knowing the element type?

Boris Kolpackov boris at codesynthesis.com
Wed Aug 16 11:43:39 EDT 2006


Hi Doug,

Chappelle, Douglas (Com US) <douglas.chappelle at siemens.com> writes:

> I'm new to XSD. Is there a way to create an object from the xml data
> without knowing the element type?

No, there is no such facility in XSD. Even if there was then it
is not clear how it would be useful. Imagine there is a generic
function parse() that takes XML document and returns the in-memory
representation. Since it can not assume anything about the type, it
returns generic xml_schema::type which is a base for all generated
types. The question is then what useful things can you do with an
instance of static type xml_schema::type if you have no idea about
its dynamic type and therefore cannot cast it to anything useful?


> If not, how is this usually handled - in particular - how do I find
> the object type? In my example I can receive hundreds of different
> objects but would like to avoid creating some sort of object factory
> to figure out what object it is and instantiate it.

I think the most straightforward way to handle XML that can be of
one of several predefined types is to peek at the root element and
then use the appropriate parsing function. Suppose we have two root
elements defined in the schema: foo and bar with types Foo and Bar
respectively, then you code could look like this:

using namespace xercesc;

DOMDocument* dom = ... // Parse XML into DOM.
DOMElement* root = dom->getDocumentElement ();
std::string name (xsd::cxx::xml::transcode (root->getLocalName ()));

if (name == "foo")
{
  std::auto_ptr<Foo> f (foo (*dom)); // Parse dom to Foo.

  // Do something useful with f.
}
else if (name == "bar")
{
  std::auto_ptr<Bar> b (bar (*dom)); // Parse dom to Bar.

  // Do something useful with b.
}


If you do not worry about performance much, you can just try calling
each parsing function in a sequence; all except one will fail:

while (true)
{
  try
  {
    std::auto_ptr<Foo> f (foo (*dom)); // Try to parse dom to Foo.

    // Do something useful with f.
    break;
  }
  catch (xml_schema::unexpected_element const&)
  {
    // Try the next function.
  }

  try
  {
    std::auto_ptr<Bar> b (bar (*dom)); // Try to parse dom to Bar.

    // Do something useful with b.
    break;
  }
  catch (xml_schema::unexpected_element const&)
  {
    // Try the next function.
  }
}

hth,
-boris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 652 bytes
Desc: Digital signature
Url : http://codesynthesis.com/pipermail/xsd-users/attachments/20060816/8e70f79c/attachment.pgp


More information about the xsd-users mailing list