1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * $Id$
20  */
21 
22 // ---------------------------------------------------------------------------
23 //  Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/util/PlatformUtils.hpp>
26 #include <xercesc/sax2/SAX2XMLReader.hpp>
27 #include <xercesc/sax2/XMLReaderFactory.hpp>
28 #include <xercesc/framework/XMLGrammarPoolImpl.hpp>
29 #include <xercesc/framework/psvi/XSModel.hpp>
30 #include <xercesc/framework/psvi/XSElementDeclaration.hpp>
31 #include <xercesc/framework/psvi/XSTypeDefinition.hpp>
32 #include <xercesc/framework/psvi/XSSimpleTypeDefinition.hpp>
33 #include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
34 #include <xercesc/framework/psvi/XSParticle.hpp>
35 #include <xercesc/framework/psvi/XSModelGroup.hpp>
36 #if defined(XERCES_NEW_IOSTREAMS)
37 #include <iostream>
38 #include <fstream>
39 #else
40 #include <iostream.h>
41 #include <fstream.h>
42 #endif
43 #include <stdlib.h>
44 #include <string.h>
45 #include <xercesc/util/OutOfMemoryException.hpp>
46 #include <xercesc/sax2/DefaultHandler.hpp>
47 
48 XERCES_CPP_NAMESPACE_USE
49 
50 // ---------------------------------------------------------------------------
51 //  Forward references
52 // ---------------------------------------------------------------------------
53 static void usage();
54 
55 void processElements(XSNamedMap<XSObject> *xsElements);
56 void processTypeDefinitions(XSNamedMap<XSObject> *xsTypeDefs);
57 void printBasic(XSObject *xsObject, const char *type);
58 void printCompositorTypeConnector(XSModelGroup::COMPOSITOR_TYPE type);
59 void processSimpleTypeDefinition(XSSimpleTypeDefinition * xsSimpleTypeDef);
60 void processComplexTypeDefinition(XSComplexTypeDefinition *xsComplexTypeDef);
61 void processParticle(XSParticle *xsParticle);
62 
63 // ---------------------------------------------------------------------------
64 //  This is a simple class that lets us do easy (though not terribly efficient)
65 //  trancoding of XMLCh data to local code page for display.
66 // ---------------------------------------------------------------------------
67 class StrX
68 {
69 public :
70     // -----------------------------------------------------------------------
71     //  Constructors and Destructor
72     // -----------------------------------------------------------------------
StrX(const XMLCh * const toTranscode)73     StrX(const XMLCh* const toTranscode)
74 {
75         // Call the private transcoding method
76         fLocalForm = XMLString::transcode(toTranscode);
77 }
78 
~StrX()79 ~StrX()
80 {
81     XMLString::release(&fLocalForm);
82 }
83 
84 
85 // -----------------------------------------------------------------------
86 //  Getter methods
87 // -----------------------------------------------------------------------
localForm() const88 const char* localForm() const
89 {
90     return fLocalForm;
91 }
92 
93 private :
94 // -----------------------------------------------------------------------
95 //  Private data members
96 //
97 //  fLocalForm
98 //      This is the local code page form of the string.
99 // -----------------------------------------------------------------------
100 char*   fLocalForm;
101 };
102 
operator <<(XERCES_STD_QUALIFIER ostream & target,const StrX & toDump)103 inline XERCES_STD_QUALIFIER ostream& operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)
104 {
105     target << toDump.localForm();
106     return target;
107 }
108 
109 class SCMPrintHandler : public DefaultHandler
110 {
111 public:
112     // -----------------------------------------------------------------------
113     //  Constructors and Destructor
114     // -----------------------------------------------------------------------
115     SCMPrintHandler();
116     ~SCMPrintHandler();
117 
getSawErrors() const118     bool getSawErrors() const
119     {
120         return fSawErrors;
121     }
122 
123 	void warning(const SAXParseException& exc);
124     void error(const SAXParseException& exc);
125     void fatalError(const SAXParseException& exc);
126     void resetErrors();
127 
128 
129 private:
130     bool            fSawErrors;
131 };
132 
SCMPrintHandler()133 SCMPrintHandler::SCMPrintHandler() :
134     fSawErrors(false)
135 {
136 }
137 
~SCMPrintHandler()138 SCMPrintHandler::~SCMPrintHandler()
139 {
140 }
141 
142 // ---------------------------------------------------------------------------
143 //  SCMPrintHandler: Overrides of the SAX ErrorHandler interface
144 // ---------------------------------------------------------------------------
error(const SAXParseException & e)145 void SCMPrintHandler::error(const SAXParseException& e)
146 {
147     fSawErrors = true;
148     XERCES_STD_QUALIFIER cerr << "\nError at file " << StrX(e.getSystemId())
149 		 << ", line " << e.getLineNumber()
150 		 << ", char " << e.getColumnNumber()
151          << "\n  Message: " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
152 }
153 
fatalError(const SAXParseException & e)154 void SCMPrintHandler::fatalError(const SAXParseException& e)
155 {
156     fSawErrors = true;
157     XERCES_STD_QUALIFIER cerr << "\nFatal Error at file " << StrX(e.getSystemId())
158 		 << ", line " << e.getLineNumber()
159 		 << ", char " << e.getColumnNumber()
160          << "\n  Message: " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
161 }
162 
warning(const SAXParseException & e)163 void SCMPrintHandler::warning(const SAXParseException& e)
164 {
165     XERCES_STD_QUALIFIER cerr << "\nWarning at file " << StrX(e.getSystemId())
166 		 << ", line " << e.getLineNumber()
167 		 << ", char " << e.getColumnNumber()
168          << "\n  Message: " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
169 }
170 
resetErrors()171 void SCMPrintHandler::resetErrors()
172 {
173     fSawErrors = false;
174 }
175 
176 // ---------------------------------------------------------------------------
177 //  Local helper methods
178 // ---------------------------------------------------------------------------
usage()179 static void usage()
180 {
181     XERCES_STD_QUALIFIER cout << "\nUsage:\n"
182     "    SCMPrint [options] <XSD file | List file>\n\n"
183     "This program parses XML Schema file(s), to show how one can\n"
184     "access the Schema Content Model information.\n\n"
185     "Options:\n"
186 	"    -f     Enable full schema constraint checking processing. Defaults to off.\n"
187     "    -l     Indicate the input file is a List File that has a list of XSD files.\n"
188     "           Default to off (Input file is a XSD file).\n"
189 	"    -?     Show this help.\n\n"
190     << XERCES_STD_QUALIFIER endl;
191 }
192 
193 // ---------------------------------------------------------------------------
194 //  Program entry point
195 // ---------------------------------------------------------------------------
main(int argC,char * argV[])196 int main(int argC, char* argV[])
197 {
198     // Check command line and extract arguments.
199     if (argC < 2)
200     {
201         usage();
202         return 1;
203     }
204 
205     // cannot return out of catch-blocks lest exception-destruction
206     // result in calls to destroyed memory handler!
207     int errorCode = 0;
208     try
209     {
210         XMLPlatformUtils::Initialize();
211     }
212 
213     catch (const XMLException& toCatch)
214     {
215         XERCES_STD_QUALIFIER cerr   << "Error during initialization! Message:\n"
216         << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
217         errorCode = 2;
218     }
219     if(errorCode) {
220         XMLPlatformUtils::Terminate();
221         return errorCode;
222     }
223 
224     bool							doList				= false;
225     bool							schemaFullChecking	= false;
226     const char*                     xsdFile             = 0;
227     int argInd;
228 
229     for (argInd = 1; argInd < argC; argInd++)
230     {
231         // Break out on first parm not starting with a dash
232         if (argV[argInd][0] != '-')
233             break;
234 
235         // Watch for special case help request
236         if (!strcmp(argV[argInd], "-?"))
237         {
238             usage();
239             return 1;
240         }
241         else if (!strcmp(argV[argInd], "-l")
242               ||  !strcmp(argV[argInd], "-L"))
243         {
244             doList = true;
245         }
246         else if (!strcmp(argV[argInd], "-f")
247               ||  !strcmp(argV[argInd], "-F"))
248         {
249             schemaFullChecking = true;
250         }
251         else
252         {
253             XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[argInd]
254                 << "', ignoring it\n" << XERCES_STD_QUALIFIER endl;
255         }
256     }
257 
258     //
259     //  There should be only one and only one parameter left, and that
260     //  should be the file name.
261     //
262     if (argInd != argC - 1)
263     {
264         usage();
265         return 1;
266     }
267 
268     XMLGrammarPool *grammarPool = 0;
269     SAX2XMLReader* parser = 0;
270     try
271     {
272         grammarPool = new XMLGrammarPoolImpl(XMLPlatformUtils::fgMemoryManager);
273 
274         parser = XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, grammarPool);
275         parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
276         parser->setFeature(XMLUni::fgXercesSchema, true);
277         parser->setFeature(XMLUni::fgXercesHandleMultipleImports, true);
278         parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
279         parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, false);
280         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
281         parser->setFeature(XMLUni::fgXercesDynamic, true);
282         parser->setProperty(XMLUni::fgXercesScannerName, (void *)XMLUni::fgSGXMLScanner);
283 
284         SCMPrintHandler handler;
285         parser->setErrorHandler(&handler);
286 
287         bool more = true;
288         bool parsedOneSchemaOkay = false;
289         XERCES_STD_QUALIFIER ifstream fin;
290 
291         // the input is a list file
292         if (doList)
293             fin.open(argV[argInd]);
294 
295         if (fin.fail()) {
296             XERCES_STD_QUALIFIER cerr <<"Cannot open the list file: " << argV[argInd] << XERCES_STD_QUALIFIER endl;
297             return 3;
298         }
299 
300         while (more)
301         {
302             char fURI[1000];
303             //initialize the array to zeros
304             memset(fURI,0,sizeof(fURI));
305 
306             if (doList) {
307                 if (! fin.eof() ) {
308                     fin.getline (fURI, sizeof(fURI));
309                     if (!*fURI)
310                         continue;
311                     else {
312                         xsdFile = fURI;
313                         XERCES_STD_QUALIFIER cerr << "==Parsing== " << xsdFile << XERCES_STD_QUALIFIER endl;
314                     }
315                 }
316                 else
317                     break;
318             }
319             else {
320                 xsdFile = argV[argInd];
321                 more = false;
322             }
323 
324             parser->loadGrammar(xsdFile, Grammar::SchemaGrammarType, true);
325             if (handler.getSawErrors())
326             {
327                 handler.resetErrors();
328             }
329             else
330             {
331                 parsedOneSchemaOkay = true;
332             }
333         }
334 
335         if (parsedOneSchemaOkay)
336         {
337             XERCES_STD_QUALIFIER cout << "********** Printing out information from Schema **********" << "\n\n";
338             bool updatedXSModel;
339             XSModel *xsModel = grammarPool->getXSModel(updatedXSModel);
340             if (xsModel)
341             {
342                 StringList *namespaces = xsModel->getNamespaces();
343                 for (unsigned i = 0; i < namespaces->size(); i++) {
344 
345                     XERCES_STD_QUALIFIER cout << "Processing Namespace:   ";
346                     const XMLCh *nameSpace = namespaces->elementAt(i);
347                     if (nameSpace && *nameSpace)
348                         XERCES_STD_QUALIFIER cout << StrX(nameSpace);
349                     XERCES_STD_QUALIFIER cout << "\n============================================" << XERCES_STD_QUALIFIER endl << XERCES_STD_QUALIFIER endl;
350 
351                     processElements(xsModel->getComponentsByNamespace(XSConstants::ELEMENT_DECLARATION,
352                                                                   nameSpace));
353                     processTypeDefinitions(xsModel->getComponentsByNamespace(XSConstants::TYPE_DEFINITION,
354                                                                          nameSpace));
355                 }
356             }
357             else
358             {
359                 XERCES_STD_QUALIFIER cout << "No XSModel to print" << "\n\n";
360             }
361         }
362         else
363         {
364             XERCES_STD_QUALIFIER cout << "Did not parse a schema document cleanly so not printing Schema for Schema XSModel information";
365         }
366 
367         XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
368     }
369     catch (const OutOfMemoryException&)
370     {
371         XERCES_STD_QUALIFIER cerr << "OutOfMemoryException during parsing: '" << xsdFile << "'\n" << XERCES_STD_QUALIFIER endl;
372         errorCode = 6;
373     }
374     catch (const XMLException& e)
375     {
376         XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << xsdFile << "'\n"
377         << "Exception message is:  \n"
378         << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
379         errorCode = 4;
380     }
381     catch (...)
382     {
383         XERCES_STD_QUALIFIER cerr << "\nUnexpected exception during parsing: '" << xsdFile << "'\n" << XERCES_STD_QUALIFIER endl;
384         errorCode = 5;
385     }
386 
387     delete parser;
388     delete grammarPool;
389     XMLPlatformUtils::Terminate();
390 
391     return errorCode;
392 }
393 
printBasic(XSObject * xsObject,const char * type)394 void printBasic(XSObject *xsObject, const char *type)
395 {
396     XERCES_STD_QUALIFIER cout << "Name:\t\t\t";
397     const XMLCh *nameSpace = xsObject->getNamespace();
398     if (nameSpace && *nameSpace) {
399         XERCES_STD_QUALIFIER cout << StrX(nameSpace) << ", ";
400     }
401     XERCES_STD_QUALIFIER cout << StrX(xsObject->getName()) << "\n";
402     XERCES_STD_QUALIFIER cout << "Component Type:\t" << type << XERCES_STD_QUALIFIER endl;
403 }
404 
processElements(XSNamedMap<XSObject> * xsElements)405 void processElements(XSNamedMap<XSObject> *xsElements)
406 {
407     if (!xsElements || xsElements->getLength() == 0) {
408         XERCES_STD_QUALIFIER cout << "no elements\n\n"  << XERCES_STD_QUALIFIER endl;
409         return;
410     }
411     for (XMLSize_t i=0; i < xsElements->getLength(); i++) {
412         XSElementDeclaration *xsElement = (XSElementDeclaration *)xsElements->item(i);
413         printBasic(xsElement, "Element");
414 
415         // Content Model
416         XSTypeDefinition *xsTypeDef = xsElement->getTypeDefinition();
417         XERCES_STD_QUALIFIER cout << "Content Model" << "\n";
418         XERCES_STD_QUALIFIER cout << "\tType:\t";
419         if (xsTypeDef->getTypeCategory() == XSTypeDefinition::SIMPLE_TYPE) {
420             XERCES_STD_QUALIFIER cout << "Simple\n";
421         } else {
422             XERCES_STD_QUALIFIER cout << "Complex\n";
423         }
424         XERCES_STD_QUALIFIER cout << "\tName:\t"
425             << StrX(xsTypeDef->getName()) << "\n";
426 
427         XERCES_STD_QUALIFIER cout << "\n--------------------------------------------" << XERCES_STD_QUALIFIER endl;
428     }
429 }
430 
processSimpleTypeDefinition(XSSimpleTypeDefinition * xsSimpleTypeDef)431 void processSimpleTypeDefinition(XSSimpleTypeDefinition * xsSimpleTypeDef)
432 {
433     XSTypeDefinition *xsBaseTypeDef = xsSimpleTypeDef->getBaseType();
434     XERCES_STD_QUALIFIER cout << "Base:\t\t\t";
435     XERCES_STD_QUALIFIER cout << StrX(xsBaseTypeDef->getName()) << XERCES_STD_QUALIFIER endl;
436 
437     int facets = xsSimpleTypeDef->getDefinedFacets();
438     if (facets) {
439         XERCES_STD_QUALIFIER cout << "Facets:\n";
440 
441         if (facets & XSSimpleTypeDefinition::FACET_LENGTH)
442                 XERCES_STD_QUALIFIER cout << "\tLength:\t\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_LENGTH)) << XERCES_STD_QUALIFIER endl;
443         if (facets & XSSimpleTypeDefinition::FACET_MINLENGTH)
444                 XERCES_STD_QUALIFIER cout << "\tMinLength:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MINLENGTH)) << XERCES_STD_QUALIFIER endl;
445         if (facets & XSSimpleTypeDefinition::FACET_MAXLENGTH)
446                 XERCES_STD_QUALIFIER cout << "\tMaxLength:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MAXLENGTH)) << XERCES_STD_QUALIFIER endl;
447         if (facets & XSSimpleTypeDefinition::FACET_PATTERN) {
448             StringList *lexicalPatterns = xsSimpleTypeDef->getLexicalPattern();
449             if (lexicalPatterns && lexicalPatterns->size()) {
450                 XERCES_STD_QUALIFIER cout << "\tPattern:\t\t";
451                 for (unsigned i = 0; i < lexicalPatterns->size(); i++) {
452                     XERCES_STD_QUALIFIER cout << StrX(lexicalPatterns->elementAt(i));
453                 }
454                 XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
455             }
456         }
457         if (facets & XSSimpleTypeDefinition::FACET_WHITESPACE)
458                 XERCES_STD_QUALIFIER cout << "\tWhitespace:\t\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_WHITESPACE)) << XERCES_STD_QUALIFIER endl;
459         if (facets & XSSimpleTypeDefinition::FACET_MAXINCLUSIVE)
460                 XERCES_STD_QUALIFIER cout << "\tMaxInclusive:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MAXINCLUSIVE)) << XERCES_STD_QUALIFIER endl;
461         if (facets & XSSimpleTypeDefinition::FACET_MAXEXCLUSIVE)
462                 XERCES_STD_QUALIFIER cout << "\tMaxExclusive:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MAXEXCLUSIVE)) << XERCES_STD_QUALIFIER endl;
463         if (facets & XSSimpleTypeDefinition::FACET_MINEXCLUSIVE)
464                 XERCES_STD_QUALIFIER cout << "\tMinExclusive:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MINEXCLUSIVE)) << XERCES_STD_QUALIFIER endl;
465         if (facets & XSSimpleTypeDefinition::FACET_MININCLUSIVE)
466                 XERCES_STD_QUALIFIER cout << "\tMinInclusive:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_MININCLUSIVE)) << XERCES_STD_QUALIFIER endl;
467         if (facets & XSSimpleTypeDefinition::FACET_TOTALDIGITS)
468                 XERCES_STD_QUALIFIER cout << "\tTotalDigits:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_TOTALDIGITS)) << XERCES_STD_QUALIFIER endl;
469         if (facets & XSSimpleTypeDefinition::FACET_FRACTIONDIGITS)
470                 XERCES_STD_QUALIFIER cout << "\tFractionDigits:\t" << StrX(xsSimpleTypeDef->getLexicalFacetValue(XSSimpleTypeDefinition::FACET_FRACTIONDIGITS)) << XERCES_STD_QUALIFIER endl;
471         if (facets & XSSimpleTypeDefinition::FACET_ENUMERATION) {
472             StringList *lexicalEnums = xsSimpleTypeDef->getLexicalEnumeration();
473             if (lexicalEnums && lexicalEnums->size()) {
474                 XERCES_STD_QUALIFIER cout << "\tEnumeration:\n";
475                 for (unsigned i = 0; i < lexicalEnums->size(); i++) {
476                     XERCES_STD_QUALIFIER cout << "\t\t\t" << StrX(lexicalEnums->elementAt(i)) << "\n";
477                 }
478                 XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
479             }
480         }
481     }
482 }
483 
printCompositorTypeConnector(XSModelGroup::COMPOSITOR_TYPE type)484 void printCompositorTypeConnector(XSModelGroup::COMPOSITOR_TYPE type)
485 {
486     switch (type) {
487         case XSModelGroup::COMPOSITOR_SEQUENCE :
488             XERCES_STD_QUALIFIER cout << ",";
489             break;
490         case XSModelGroup::COMPOSITOR_CHOICE :
491             XERCES_STD_QUALIFIER cout << "|";
492             break;
493         case XSModelGroup::COMPOSITOR_ALL :
494             XERCES_STD_QUALIFIER cout << "*";
495             break;
496     }
497 }
498 
processParticle(XSParticle * xsParticle)499 void processParticle(XSParticle *xsParticle)
500 {
501     if (!xsParticle) {
502         XERCES_STD_QUALIFIER cout << "xsParticle is NULL";
503         return;
504     }
505     XSParticle::TERM_TYPE termType = xsParticle->getTermType();
506     if (termType == XSParticle::TERM_ELEMENT) {
507         XSElementDeclaration *xsElement = xsParticle->getElementTerm();
508         XERCES_STD_QUALIFIER cout << StrX(xsElement->getName());
509     } else if (termType == XSParticle::TERM_MODELGROUP) {
510         XERCES_STD_QUALIFIER cout << "(";
511 
512         XSModelGroup *xsModelGroup = xsParticle->getModelGroupTerm();
513         XSModelGroup::COMPOSITOR_TYPE compositorType = xsModelGroup->getCompositor();
514         XSParticleList *xsParticleList = xsModelGroup->getParticles();
515         for (unsigned i = 0; i < xsParticleList->size()-1; i++) {
516             processParticle(xsParticleList->elementAt(i));
517             printCompositorTypeConnector(compositorType);
518         }
519         processParticle(xsParticleList->elementAt(xsParticleList->size()-1));
520 
521         XERCES_STD_QUALIFIER cout << ")";
522     } else if (termType == XSParticle::TERM_WILDCARD) {
523         XERCES_STD_QUALIFIER cout << "* (wildcard)";
524     }
525 }
526 
processComplexTypeDefinition(XSComplexTypeDefinition * xsComplexTypeDef)527 void processComplexTypeDefinition(XSComplexTypeDefinition *xsComplexTypeDef)
528 {
529     XSTypeDefinition *xsBaseTypeDef = xsComplexTypeDef->getBaseType();
530     if (xsBaseTypeDef) {
531         XERCES_STD_QUALIFIER cout << "Base:\t\t\t";
532         XERCES_STD_QUALIFIER cout << StrX(xsBaseTypeDef->getName()) << "\n";
533     }
534 
535     XERCES_STD_QUALIFIER cout << "Content Model:\t";
536     XSComplexTypeDefinition::CONTENT_TYPE contentType = xsComplexTypeDef->getContentType();
537     if (contentType == XSComplexTypeDefinition::CONTENTTYPE_ELEMENT ||
538         contentType == XSComplexTypeDefinition::CONTENTTYPE_MIXED) {
539         processParticle(xsComplexTypeDef->getParticle());
540         XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
541     }
542 }
543 
processTypeDefinitions(XSNamedMap<XSObject> * xsTypeDefs)544 void processTypeDefinitions(XSNamedMap<XSObject> *xsTypeDefs)
545 {
546     if (!xsTypeDefs) return;
547 
548     for (XMLSize_t i=0; i < xsTypeDefs->getLength(); i++) {
549         XSTypeDefinition *xsTypeDef = (XSTypeDefinition *)xsTypeDefs->item(i);
550 
551         printBasic(xsTypeDef, "Type Definition");
552 
553         // Content Model
554         XERCES_STD_QUALIFIER cout << "Category:\t";
555         if (xsTypeDef->getTypeCategory() == XSTypeDefinition::SIMPLE_TYPE) {
556             XERCES_STD_QUALIFIER cout << "\tSimple\n";
557             processSimpleTypeDefinition((XSSimpleTypeDefinition *)xsTypeDef);
558         } else {
559             XERCES_STD_QUALIFIER cout << "\tComplex\n";
560             processComplexTypeDefinition((XSComplexTypeDefinition *)xsTypeDef);
561         }
562 
563         XERCES_STD_QUALIFIER cout << "\n--------------------------------------------" << XERCES_STD_QUALIFIER endl;
564     }
565 }
566