[xsd-users] Sort of XML "reflection"

Paquette, Patrick PaquetP at navcanada.ca
Wed Nov 18 12:20:39 EST 2009


 
Hi Bill,

Bill writes:
> 
> I think that you could add virtual functionality to the base class.
> You can do this by wrapping the XSD generated base and all of the
> derived classes.  The method would be something like,
> 
>  virtual boolean amI(std::string type) = 0;
> 
> That would be elegant in that adding new types would not require the
> base to know about them.  However, you can also create the same thing
> with a mapping of typeid and strings.  This can be a completely static
> method.
> 
>  static boolean isKind(base * ptr, std::string);
> 
> You then need a map of all derived types to the matching string (or
> the string could be the typeid() name).
> 
> struct { 
>   char * class_name;
>   char * given_name;
> } animal_map[] = {
>   { typeid(elephant).name, "elephant" },
>   { typeid(mole).name, "mole" },
>   { typeid(monkey).name, "monkey" },
>   { typeid(porpoise).name, "porpoise" },
>   { typeid(zebra).name, "zebra }
> };
> 
>   // get animal map index matching given name.
>   return strcmp(typeid(*ptr).name,animal_map[index].class_name) == 0;
> 

I'm actually not trying to map types, I'm trying to map elements.
Quoting myself: "a caller will be passing a string representing the name
of one of these ELEMENTS of the complex type T.  I'd like to determine
if such an ELEMENT exists, and if it does, get a reference to all
occurences of them to a sequence of B&".
The sequence of B& is because I know all elements will be at least type
B.

> This doesn't require as many XSD wrappers, but is less fool-proof to
> addition of derived classes.
> 
> In both cases, the predicate functions can be used to run through a
> collection to 'filter' your desired targets.
> 
> btw, I think this is a C++ question as opposed to XSD?

My goal here is to reflect on the class generated by XSD to see if it
contains a function to access an element whos name is a string that is
provided as an argument, and if so, get a class of type at least B that
references that element.  I'm aware that C++ has a limited reflection
capability, but I figured I can do this if I had access to the DOM
association, but I do not because I created the instance of T without
calling the parser (I called the default constructor to the generated
class that binds to the complex type T).

I was hoping that because I'm using the XSD compiler, I get a sort of
reflection API in C++ for free (perhaps there was some sort of flag in
the XSD compiler I missed that creates the DOM associated elements when
instances of the binding classes are created from the constructors,
which by default was off).  Right now, it takes a bit of work to do it,
but with support for Xpath coming, you get something like reflection in
all classes generated by XSD.

I'm now exploring the idea of creating a DOMDocument first at the point
when I know all element names that need to be accessed this way (which I
know already from a top level function that has this list of names), and
when I create an instance of T, I won't call the default constructor, I
pass it the DOMDocument, with the keep_dom flag set.

> 
> fwiw,

Thanks for your input Bill,
Patrick




More information about the xsd-users mailing list