@@ -27,12 +27,13 @@ namespace classdesc
2727 {
2828 bool complete; // set to true if current type definition is complete
2929 bool sequenceAdded;
30+ bool derivedFromString; // True if derived from string - expect data
3031 string name, description, baseClass;
3132 TypeBeingAddedTo (const string& name=" " , const string& d=" " , bool complete=false ):
32- complete (complete), sequenceAdded(false ), name(name), description(d) {}
33+ complete (complete), sequenceAdded(false ), derivedFromString( false ), name(name), description(d) {}
3334 };
3435
35- std::vector<TypeBeingAddedTo> typeBeingaddedTo ;
36+ std::vector<TypeBeingAddedTo> typeBeingAddedTo ;
3637 std::set<string> written; // record when a type is written
3738
3839 void outputType (std::ostream& o, const string& type)
@@ -62,37 +63,61 @@ namespace classdesc
6263
6364 xsd_generate_t (): optional(false ) {}
6465
66+ void setTypeBeingAddedToIsDerivedFromString () {
67+ if (!typeBeingAddedTo.back ().complete )
68+ {
69+ // replace first open tag with one with mixed attribute
70+ std::string type=typeBeingAddedTo.back ().name ;
71+ std::string& def=xsdDefs[type];
72+ std::string::size_type n=def.find (' >' );
73+ if (n!=std::string::npos)
74+ def=" <xs:complexType mixed=\" true\" name=\" " +type+" \" >" +
75+ def.substr (n+1 );
76+ }
77+ }
78+
6579 // / add an attribute \a name with XSD type \a memberType
6680 void addMember (const string& name, const string& memberType)
6781 {
6882 if (!name.empty () &&
69- !typeBeingaddedTo .empty () && !typeBeingaddedTo .back ().complete )
83+ !typeBeingAddedTo .empty () && !typeBeingAddedTo .back ().complete )
7084 {
71- if (!typeBeingaddedTo .back ().sequenceAdded )
72- xsdDefs[typeBeingaddedTo .back ().name ]+=" <xs:sequence>\n " ;
73- typeBeingaddedTo .back ().sequenceAdded =true ;
74- xsdDefs[typeBeingaddedTo .back ().name ]+=
85+ if (!typeBeingAddedTo .back ().sequenceAdded )
86+ xsdDefs[typeBeingAddedTo .back ().name ]+=" <xs:sequence>\n " ;
87+ typeBeingAddedTo .back ().sequenceAdded =true ;
88+ xsdDefs[typeBeingAddedTo .back ().name ]+=
7589 " <xs:element name=\" " +name+" \" type=\" "
7690 +memberType+(optional?" \" minOccurs=\" 0" :" " )+" \" />\n " ;
77- addDependency (typeBeingaddedTo .back ().name , memberType);
91+ addDependency (typeBeingAddedTo .back ().name , memberType);
7892 }
7993 }
8094
8195 // / add a base class to the current definition
8296 void addBase (const string& base)
8397 {
84- if (!typeBeingaddedTo .empty () && !typeBeingaddedTo .back ().complete )
98+ if (!typeBeingAddedTo .empty () && !typeBeingAddedTo .back ().complete )
8599 {
86- if (typeBeingaddedTo .back ().baseClass .empty ())
100+ if (typeBeingAddedTo .back ().baseClass .empty ())
87101 {
88- xsdDefs[typeBeingaddedTo.back ().name ]+=
102+ // classes derived from std::string (explicity
103+ // qualified), can also have string data in the content
104+ // of the XML tag
105+ if (base==" xs::string" )
106+ {
107+ string& def=xsdDefs[typeBeingAddedTo.back ().name ];
108+ std::string::size_type endFirstTag=def.find (' >' );
109+ if (endFirstTag!=string::npos && endFirstTag>0 )
110+ def=def.substr (0 ,endFirstTag-1 )+" mixed=\" true\" " +
111+ def.substr (endFirstTag);
112+ }
113+ xsdDefs[typeBeingAddedTo.back ().name ]+=
89114 " <xs:complexContent>\n "
90115 " <xs:extension base=\" " +base+" \" >\n " ;
91- typeBeingaddedTo .back ().baseClass =base;
116+ typeBeingAddedTo .back ().baseClass =base;
92117 }
93- else if (typeBeingaddedTo .back ().baseClass !=base)
118+ else if (typeBeingAddedTo .back ().baseClass !=base)
94119 throw exception
95- (" Multiple inheritance not supported: " +typeBeingaddedTo .back ().name );
120+ (" Multiple inheritance not supported: " +typeBeingAddedTo .back ().name );
96121 }
97122 }
98123
@@ -109,35 +134,40 @@ namespace classdesc
109134 // / xsd_generate()
110135 void openType (const string& type, const string& description)
111136 {
112- typeBeingaddedTo .push_back
137+ typeBeingAddedTo .push_back
113138 (TypeBeingAddedTo (type, description, xsdDefs.count (type)>0 ));
114- if (!typeBeingaddedTo.back ().complete )
115- xsdDefs[type]=" <xs:complexType name=\" " +type+" \" >\n " ;
139+ if (!typeBeingAddedTo.back ().complete )
140+ {
141+ xsdDefs[type]=" <xs:complexType name=\" " +type+" \" >\n " ;
142+ }
116143 }
117144 // / complete type definition - matching last nested openType
118145 void closeType ()
119146 {
120- if (!typeBeingaddedTo .empty () && !typeBeingaddedTo .back ().complete )
147+ if (!typeBeingAddedTo .empty () && !typeBeingAddedTo .back ().complete )
121148 {
122149 // allow schema to be extensible - either for polymorphic
123150 // reasons, or for future extensibility
124- xsdDefs[typeBeingaddedTo.back ().name ]+=
125- " <xs:any minOccurs=\" 0\" "
126- " maxOccurs=\" unbounded\" processContents=\" lax\" />\n " ;
127- if (typeBeingaddedTo.back ().sequenceAdded )
128- xsdDefs[typeBeingaddedTo.back ().name ]+=" </xs:sequence>\n " ;
129- if (!typeBeingaddedTo.back ().baseClass .empty ())
130- xsdDefs[typeBeingaddedTo.back ().name ]+=" </xs:extension>\n "
151+ // namespace attribute to solve Unique Particle Attribution (UPA) rule in XSD 1.0
152+ if (typeBeingAddedTo.back ().baseClass .empty ())
153+ xsdDefs[typeBeingAddedTo.back ().name ]+=
154+ " <xs:any minOccurs=\" 0\" "
155+ " namespace=\" ##other\" "
156+ " maxOccurs=\" unbounded\" processContents=\" lax\" />\n " ;
157+ if (typeBeingAddedTo.back ().sequenceAdded )
158+ xsdDefs[typeBeingAddedTo.back ().name ]+=" </xs:sequence>\n " ;
159+ if (!typeBeingAddedTo.back ().baseClass .empty ())
160+ xsdDefs[typeBeingAddedTo.back ().name ]+=" </xs:extension>\n "
131161 " </xs:complexContent>\n " ;
132- xsdDefs[typeBeingaddedTo .back ().name ]+=" </xs:complexType>\n " ;
162+ xsdDefs[typeBeingAddedTo .back ().name ]+=" </xs:complexType>\n " ;
133163 }
134- typeBeingaddedTo .pop_back ();
164+ typeBeingAddedTo .pop_back ();
135165 }
136166
137167 string currentDescription () const
138168 {
139- if (!typeBeingaddedTo .empty ())
140- return typeBeingaddedTo .back ().description ;
169+ if (!typeBeingAddedTo .empty ())
170+ return typeBeingAddedTo .back ().description ;
141171 else
142172 return " " ;
143173 }
@@ -459,7 +489,11 @@ namespace classdesc
459489
460490 template <class T >
461491 void xsd_generate_onbase (xsd_generate_t & g, const string& d, T a)
462- {xsd_generate (g,d+basename<T>(),a);}
492+ {
493+ if (is_string<T>::value)
494+ g.setTypeBeingAddedToIsDerivedFromString ();
495+ xsd_generate (g,d+basename<T>(),a);
496+ }
463497
464498 template <class T >
465499 typename enable_if<EverythingElse<T>, void >::T
0 commit comments