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

Chappelle, Douglas (Com US) douglas.chappelle at siemens.com
Thu Aug 17 15:37:43 EDT 2006


Thanks for the quick response, it was very helpful!

A couple more questions..

[1] I have an object factory that returns auto_ptr<type> (type of course
being the base type of the xsd objects created). Is there an easy way
(api) to find out what element this is?

For example:

     auto_ptr<type> obj;
     obj = myXsdObject(xml_data);
     obj->? Returns "myXsdObject"

[2] I'm reading through the Tree User manual looking for an easy way to
serialize an auto_ptr<type> to an output stream. I see section 4.5
Serializing to std::ostream but is there a way to do this without
needing to build a namespace infomap? 

Thanks again,
Doug

-----Original Message-----
From: Boris Kolpackov [mailto:boris at codesynthesis.com] 
Sent: Wednesday, August 16, 2006 11:44 AM
To: Chappelle, Douglas (Com US)
Cc: xsd-users at codesynthesis.com
Subject: Re: [xsd-users] How to create an object from the xml data
without knowing the element type?

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




More information about the xsd-users mailing list