9 #ifndef XSD_GENERATE_BASE 10 #define XSD_GENERATE_BASE 11 #include "classdesc.h" 22 std::map<string, string> xsdDefs;
23 std::map<string, std::set<string> > dependencies;
25 struct TypeBeingAddedTo
29 string name, description, baseClass;
30 TypeBeingAddedTo(
const string& name=
"",
const string& d=
"",
bool complete=
false):
31 complete(complete), sequenceAdded(
false), name(name), description(d) {}
34 std::vector<TypeBeingAddedTo> typeBeingaddedTo;
35 std::set<string> written;
37 void outputType(std::ostream& o,
const string& type)
39 if (!written.insert(type).second)
return;
41 const std::set<string>& deps=dependencies[type];
42 for (std::set<string>::const_iterator d=deps.begin(); d!=deps.end(); ++d)
65 void addMember(
const string& name,
const string& memberType)
68 !typeBeingaddedTo.empty() && !typeBeingaddedTo.back().complete)
70 if (!typeBeingaddedTo.back().sequenceAdded)
71 xsdDefs[typeBeingaddedTo.back().name]+=
" <xs:sequence>\n";
72 typeBeingaddedTo.back().sequenceAdded=
true;
73 xsdDefs[typeBeingaddedTo.back().name]+=
74 " <xs:element name=\""+name+
"\" type=\"" 75 +memberType+(optional?
"\" minOccurs=\"0":
"")+
"\"/>\n";
83 if (!typeBeingaddedTo.empty() && !typeBeingaddedTo.back().complete)
85 if (typeBeingaddedTo.back().baseClass.empty())
87 xsdDefs[typeBeingaddedTo.back().name]+=
88 " <xs:complexContent>\n" 89 " <xs:extension base=\""+base+
"\">\n";
90 typeBeingaddedTo.back().baseClass=base;
92 else if (typeBeingaddedTo.back().baseClass!=base)
94 (
"Multiple inheritance not supported: "+typeBeingaddedTo.back().name);
102 if (dependency.substr(0,4)==
"tns:")
103 dependencies[type].insert(dependency.substr(4));
109 void openType(
const string& type,
const string& description)
111 typeBeingaddedTo.push_back
112 (TypeBeingAddedTo(type, description, xsdDefs.count(type)>0));
113 if (!typeBeingaddedTo.back().complete)
114 xsdDefs[type]=
" <xs:complexType name=\""+type+
"\">\n";
119 if (!typeBeingaddedTo.empty() && !typeBeingaddedTo.back().complete)
123 xsdDefs[typeBeingaddedTo.back().name]+=
124 " <xs:any minOccurs=\"0\" " 125 "maxOccurs=\"unbounded\" processContents=\"lax\"/>\n";
126 if (typeBeingaddedTo.back().sequenceAdded)
127 xsdDefs[typeBeingaddedTo.back().name]+=
" </xs:sequence>\n";
128 if (!typeBeingaddedTo.back().baseClass.empty())
129 xsdDefs[typeBeingaddedTo.back().name]+=
" </xs:extension>\n" 130 " </xs:complexContent>\n";
131 xsdDefs[typeBeingaddedTo.back().name]+=
" </xs:complexType>\n";
133 typeBeingaddedTo.pop_back();
136 string currentDescription()
const 138 if (!typeBeingaddedTo.empty())
139 return typeBeingaddedTo.back().description;
147 if (xsdDefs.count(type)==0)
154 void output(std::ostream& o,
const string& targetNS)
157 o<<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
158 o<<
"<xs:schema targetNamespace=\"";
160 o<<
"\"\n xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n";
161 o<<
" xmlns:tns=\""<<targetNS<<
"\"\n";
162 o<<
" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n";
164 for (std::map<string, string>::const_iterator i=xsdDefs.begin();
165 i!=xsdDefs.end(); ++i)
166 outputType(o, i->first);
168 o<<
" <xs:element name=\""<<rootName<<
"\" type=\""<<rootType<<
"\"/>\n";
178 const char* what()
const throw()
179 {
return msg.c_str();}
198 inline string transformTypeName(
string x)
200 for (string::size_type i=0; i<x.length(); ++i)
206 template <
class T>
string xsd_typeName()
207 {
return "tns:"+transformTypeName(typeName<T>());}
213 Or<is_fundamental<T>,is_container<T> >,
223 if (!d.empty() && d.find(
'.')==string::npos)
226 g.rootType=xsd_typeName<T>();
229 if (g.currentDescription()==d)
233 g.
openType(transformTypeName(typeName<T>()), d);
240 template <>
inline string xsd_typeName<bool>() {
return "xs:boolean";}
241 template <>
inline string xsd_typeName<char>() {
return "xs:string";}
242 template <>
inline string xsd_typeName<signed char>() {
return "xs:string";}
243 template <>
inline string xsd_typeName<short>() {
return "xs:short";}
244 template <>
inline string xsd_typeName<int>() {
return "xs:int";}
245 template <>
inline string xsd_typeName<long>() {
return "xs:long";}
246 template <>
inline string xsd_typeName<unsigned char>() {
return "xs:string";}
247 template <>
inline string xsd_typeName<unsigned short>() {
return "xs:unsignedShort";}
248 template <>
inline string xsd_typeName<unsigned int>() {
return "xs:unsignedInt";}
249 template <>
inline string xsd_typeName<unsigned long>() {
return "xs:unsignedLong";}
252 template <>
inline string xsd_typeName<long long>() {
return "xs:long";}
253 template <>
inline string xsd_typeName<unsigned long long>() {
return "xs:unsignedLong";}
256 template <>
inline string xsd_typeName<float>() {
return "xs:float";}
257 template <>
inline string xsd_typeName<double>() {
return "xs:double";}
259 template <>
inline string xsd_typeName<long double>() {
return "xs:double";}
260 template <>
inline string xsd_typeName<string>() {
return "xs:string";}
261 template <>
inline string xsd_typeName<std::wstring>() {
return "xs:string";}
266 {g.
addMember(tail(d),xsd_typeName<T>());}
269 void xsd_generate(
xsd_generate_t& g,
const string& d,
const std::basic_string<T>& a)
276 int dims,
size_t ncopies, ...)
278 std::ostringstream type;
279 type <<
"__builtin_array_"+transformTypeName(typeName<T>())<<
"_"<<ncopies;
281 va_start(ap,ncopies);
282 for (
int i=1; i<dims; i++)
285 int dim=va_arg(ap,
int);
291 std::ostringstream os;
292 os<<
" <xs:complexType name=\""+type.str()+
"\">\n";
293 os<<
" <xs:sequence minOccurs=\""<<ncopies<<
294 "\" maxOccurs=\""<<ncopies<<
"\">\n";
295 os<<
" <xs:element name=\""<<typeName<T>()<<
"\" type=\""<<
296 xsd_typeName<T>()<<
"\"/>\n";
297 os<<
" </xs:sequence>\n";
298 os<<
" </xs:complexType>\n";
318 string type=transformTypeName(typeName<E>());
319 std::ostringstream os;
320 os <<
" <xs:simpleType name=\""<<type<<
"\">\n";
321 os <<
" <xs:restriction base=\"xs:string\">\n";
322 for (
typename EnumKeys<E>::iterator i=enum_keysData<E>::keys.begin();
323 i!=enum_keysData<E>::keys.end(); ++i)
324 os <<
" <xs:enumeration value=\""<<i->second<<
"\"/>\n";
325 os <<
" </xs:restriction>\n";
326 os <<
" </xs:simpleType>\n";
336 std::ostringstream os;
338 string eName=typeName<typename T::value_type>().c_str();
339 eName=eName.substr(0,eName.find(
'<'));
341 const char *el=eName.c_str()+eName.length();
342 while (el!=eName.c_str() && *(el-1)!=
' ' && *(el-1)!=
':') el--;
344 string type=transformTypeName(typeName<T>());
345 os <<
" <xs:complexType name=\"" << type <<
"\">\n";
346 os <<
" <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n";
347 os <<
" <xs:element name=\""<<el<<
348 "\" type=\""<<xsd_typeName<typename T::value_type>()<<
"\"/>\n";
349 os <<
" </xs:sequence>\n";
350 os <<
" </xs:complexType>\n";
353 g.
addDependency(type, xsd_typeName<typename T::value_type>());
355 xsd_generate(g,
"",
typename T::value_type());
359 template <
class T,
class U>
360 void xsd_generate(
xsd_generate_t& g,
const string& d,
const std::pair<T,U>& a)
362 g.
openType(transformTypeName(typeName<std::pair<T,U> >()), d);
363 xsd_generate(g,d+
".first",a.first);
364 xsd_generate(g,d+
".second",a.second);
372 template <
class C,
class T>
373 void xsd_generate(
xsd_generate_t& g,
const string& d, C& c,
const T& a) {}
378 template <
class T,
class U>
386 void xsd_generate(
xsd_generate_t& g,
const string& d,
const shared_ptr<T>& a)
389 xsd_generate(g,d,*a);
394 {xsd_generate(g,d+basename<T>(),a);}
398 using classdesc::xsd_generate;
399 using classdesc::xsd_generate_onbase;
Definition: classdesc.h:326
void addDependency(const string &type, const string &dependency)
add a dependency between type and dependency (XSD qualifed name)
Definition: xsd_generate_base.h:99
Definition: xsd_generate_base.h:186
void addMember(const string &name, const string &memberType)
add an attribute name with XSD type memberType
Definition: xsd_generate_base.h:65
Definition: classdesc.h:623
Definition: classdesc.h:626
Definition: xsd_generate_base.h:210
bool optional
set to true if next addMember refers to an optional element
Definition: xsd_generate_base.h:51
Definition: xsd_generate_base.h:173
Definition: classdesc.h:588
void openType(const string &type, const string &description)
Definition: xsd_generate_base.h:109
void defineType(const string &type, const string &def)
add a complete XSD definition for type
Definition: xsd_generate_base.h:145
void closeType()
complete type definition - matching last nested openType
Definition: xsd_generate_base.h:117
void output(std::ostream &o, const string &targetNS)
Definition: xsd_generate_base.h:154
RAII helper class to set optional to opt for current scope.
Definition: xsd_generate_base.h:54
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
void addBase(const string &base)
add a base class to the current definition
Definition: xsd_generate_base.h:81
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:249
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
base class for exceptions thrown by classdesc
Definition: classdesc.h:366
Definition: classdesc.h:704
string rootName
name of the root element, and its XSD type, in the Schema
Definition: xsd_generate_base.h:49
Definition: xsd_generate_base.h:20