[xsd-users] Complex type with mixed content

Boris Kolpackov boris at codesynthesis.com
Mon Aug 16 09:33:50 EDT 2010


Hi Barrie,

Barrie Kovish <barrie.kovish at singularsoftware.com> writes:

> <sample>
>     2000 
> </sample>
> 
> <sample>
>      <freq>
>          20
>      </freq>
>      <phase>
>          2.17
>      </phase>
> </sample>
> 
> <xs:element name='sample'>
>     <xs:complexType mixed='true'>
>         <xs:choice minOccurs='0' maxOccurs='unbounded'>
>             <xs:element ref='freq'/>
>             <xs:element ref='phase'/>
>         </xs:choice>
>     </xs:complexType>
> </xs:element>
>
> Is there a simpler solution than implementing a custom type by had?

No, unfortunately not. You will need to customize the 'sample' type,
however, the implementation can be based on the generated version
(which will handle the case where there are nested elements) with
the customization simply handling the text-only case. Here is how
this can be done:

1. Customize the 'sample' type so that there is also the generated
   version, say 'sample_base'. Inherit 'sample' from 'sample_base'
   and add a string member for the text content (say, text_).

2. In the parsing constructor of the 'sample' class you can do
   something like this:

  sample::
  sample (const xercesc::DOMElement& e,
          xml_schema::flags f,
          xml_schema::container* c)
      : sample_base (e, f, c)
  {
    // Check if we've got the text-only case.
    //
    if (e.getFirstChildElement () == 0)
    {
      // xsd::cxx::tree::text_content is in <xsd/cxx/tree/text.hxx>
      //
      text_ = xsd::cxx::tree::text_content<char> (e);
    }
  }

3. In the serialization operator for the 'sample' class you can
   do something like this:

  void
  operator<< (xercesc::DOMElement& e, const sample& x)
  {
    if (text_.empty ())
    {
      const sample_base& b (x);
      e << b;
    }
    else
    {
      e.setTextContent (xml::string (text_).c_str ());
    }
  }

> Also we don't actually use any of the content of the <sample> element.
> However we do need to preserve it between reading in the XML file 
> modifying the XML and then writing it out.

In this case another alternative would be to store the content as a DOM
document fragment. The 'mixed' example in the examples/cxx/tree/custom/
directory does exactly this and you can copy the code pretty much
verbatim.

Boris



More information about the xsd-users mailing list