[xsd-users] Error in containers.hxx

Boris Kolpackov boris at codesynthesis.com
Fri Oct 9 13:08:00 EDT 2009


Hi Carl,

Carl <xsd at faultline.com> writes:

> I am getting errors when compiling a file. I *think* the errors have to  
> do with not having an == operator for the xml_schema::type class. 

Yes, I think you are right. To understand why xml_schema::type doesn't
provide operator== here is some background on the problem. xml_schema::type
is a mapping for xsd:anyType type. This type is special in that it can
contain anything: any attributes, any elements, and any text in between
them. This type is seldom used explicitly in schemas, except as an abstract
base type when polymorphism is in use.

However, one design aspect of XML Schema (unfortunate, IMO) is that if
you forget to specify the type attribute for an element, by default it
becomes xsd:anyType. So here is an example from your schema:

<xsd:element name="WireIdentifier">
  <xsd:annotation>
    <xsd:documentation>Wire Transfer Indentifier</xsd:documentation>
  </xsd:annotation>
</xsd:element>

I don't think the author(s) of this schema meant to use anyType and
allow, say, something like this (which is legal, according to this
schema):

<WireIdentifier>
  <xhtml>
    <... Massive XHTML document goes here ...>
  </xhtml>
</WireIdentifier>

All they probably wanted was to allow a text string and xsd:string 
would have been a much better choice for this element's type.

Because it is hard to guess what each schema author actually wants
from anyType, mapping this type to C++ is hard. Some may want it
not to contain anything since it is used as an abstract base class 
for all generated classes. Others may want it to contain a string
representation of the content. And some may want a full-blown DOM
fragment. To resolve this we decided to map anyType to a type that 
doesn't contain any data and to allow the user to customize it if 
necessary. Since this type doesn't contain anything, it is not clear
how to compare two instances of it. Are they always equal? Or always
unequal? I don't think any one of these options is particularly good
so we left it unimplemented as some kind of a warning.

In your case there are quite a few places where the schema uses anyType
as an equivalent, it seems, for xsd:string (The XSD compiler warns of 
all such places). One way to resolve this would be to customize anyType
and provide a string member which contains the data. Then you will be
able to access this data and provide a sensible implementation for
operator==. 

One tricky part of this customization is that you only want to extract
and store the element's content if xml_schema::type is used by itself.
If it is used as a base then that means the derived class will parse
the data into the object model. The same goes for serialization. One 
way to detect this situation is to use the typeid operator. Here is an 
outline of how this might look:

class type: xml_schema::type_base
{
public:

  type (const DOMElement& e, ...)
  {
    if (typeid (type) == typeid (*this))
    {
      // anyType is used by itself; extract the text and store it in data_
    }
  }

  const std::string& 
  data () const
  {
    return data_;
  }

  void
  data (const std::string& data)
  {
    data_ = data;
  }

private:
  std::string data_;
};

There is the 'comments' example in the examples/cxx/tree/custom/ directory
that shows how to customize anyType.


Boris




More information about the xsd-users mailing list