source: NonGTP/Xerces/xerces/samples/SEnumVal/SEnumVal.cpp @ 358

Revision 358, 20.5 KB checked in by bittner, 19 years ago (diff)

xerces added

Line 
1/*
2 * Copyright 2001,2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * $Id: SEnumVal.cpp,v 1.19 2004/09/08 13:55:34 peiyongz Exp $
19 * $Log: SEnumVal.cpp,v $
20 * Revision 1.19  2004/09/08 13:55:34  peiyongz
21 * Apache License Version 2.0
22 *
23 * Revision 1.18  2004/09/02 14:59:30  cargilld
24 * Add OutOfMemoryException block to samples.
25 *
26 * Revision 1.17  2003/08/07 21:21:38  neilg
27 * fix segmentation faults that may arise when the parser throws exceptions during document parsing.  In general, XMLPlatformUtils::Terminate() should not be called from within a catch statement.
28 *
29 * Revision 1.16  2003/05/30 09:36:36  gareth
30 * Use new macros for iostream.h and std:: issues.
31 *
32 * Revision 1.15  2003/02/05 18:53:24  tng
33 * [Bug 11915] Utility for freeing memory.
34 *
35 * Revision 1.14  2003/01/14 15:32:45  knoaman
36 * [Bug 16024] SchemaSymbols.hpp conflicts C++ Builder 6 dir.h
37 *
38 * Revision 1.13  2002/11/05 21:46:20  tng
39 * Explicit code using namespace in application.
40 *
41 * Revision 1.12  2002/07/12 15:51:52  knoaman
42 * Retrieve the root grammar instead of using the validator.
43 * Modify the way we print substitution group info.
44 *
45 * Revision 1.11  2002/06/25 15:30:46  peiyongz
46 * Bug#10067: SEnumVal bugs found when porting to Visual Studio .NET
47 *                     projects, patch from Robert Buck (rbuck@mathworks.com )
48 *
49 * Revision 1.10  2002/05/08 18:18:46  knoaman
50 * Fix bor bug 8301: INFINITY used as enum member.
51 *
52 * Revision 1.9  2002/04/17 20:18:08  tng
53 * [Bug 7493] The word "occured" is misspelled and it is a global error.
54 *
55 * Revision 1.8  2002/02/20 20:30:11  peiyongz
56 * Make the code compilable on Solaris 2.6's CC
57 *
58 * Revision 1.7  2002/02/14 15:14:58  peiyongz
59 * getEnumString()
60 *
61 * Revision 1.6  2002/02/01 22:41:28  peiyongz
62 * sane_include
63 *
64 * Revision 1.5  2001/11/22 14:47:48  tng
65 * Use the phrase "Grammar" instead of "Validator" in EnumVal and SEnumVal Description.
66 *
67 * Revision 1.4  2001/11/21 22:09:49  peiyongz
68 * Copy Right date
69 *
70 * Revision 1.3  2001/11/21 19:05:23  peiyongz
71 * SEnumVal: GrammarType checked
72 *
73 *
74 */
75// ---------------------------------------------------------------------------
76//  Includes
77// ---------------------------------------------------------------------------
78#include <xercesc/util/NameIdPool.hpp>
79#include <xercesc/util/PlatformUtils.hpp>
80#include <xercesc/framework/XMLValidator.hpp>
81#include <xercesc/parsers/SAXParser.hpp>
82#include <xercesc/validators/schema/SchemaValidator.hpp>
83#include <xercesc/validators/common/ContentSpecNode.hpp>
84#include <xercesc/validators/schema/SchemaSymbols.hpp>
85#include <xercesc/util/OutOfMemoryException.hpp>
86#if defined(XERCES_NEW_IOSTREAMS)
87#include <iostream>
88#else
89#include <iostream.h>
90#endif
91#include <stdlib.h>
92#include <string.h>
93
94
95XERCES_CPP_NAMESPACE_USE
96
97// ---------------------------------------------------------------------------
98//  Forward references
99// ---------------------------------------------------------------------------
100static void usage();
101
102void process(char* const);
103void processAttributes( XMLAttDefList& attList, bool margin = false );
104void processDatatypeValidator( const DatatypeValidator*, bool margin = false
105);
106void processContentSpecNode( const ContentSpecNode* specNode, bool margin =
107false );
108
109// ---------------------------------------------------------------------------
110//  This is a simple class that lets us do easy (though not terribly efficient)
111//  trancoding of XMLCh data to local code page for display.
112// ---------------------------------------------------------------------------
113class StrX
114{
115public :
116    // -----------------------------------------------------------------------
117    //  Constructors and Destructor
118    // -----------------------------------------------------------------------
119    StrX(const XMLCh* const toTranscode)
120    {
121        // Call the private transcoding method
122        fLocalForm = XMLString::transcode(toTranscode);
123    }
124
125    ~StrX()
126    {
127        XMLString::release(&fLocalForm);
128    }
129
130
131    // -----------------------------------------------------------------------
132    //  Getter methods
133    // -----------------------------------------------------------------------
134    const char* localForm() const
135    {
136        return fLocalForm;
137    }
138
139private :
140    // -----------------------------------------------------------------------
141    //  Private data members
142    //
143    //  fLocalForm
144    //      This is the local code page form of the string.
145    // -----------------------------------------------------------------------
146    char*   fLocalForm;
147};
148
149inline XERCES_STD_QUALIFIER ostream& operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)
150{
151    target << toDump.localForm();
152    return target;
153}
154
155// ---------------------------------------------------------------------------
156//  Local helper methods
157// ---------------------------------------------------------------------------
158static void usage()
159{
160    XERCES_STD_QUALIFIER cout << "\nUsage:\n"
161            "    SEnumVal <XML file>\n\n"
162            "This program parses a file, then shows how to enumerate the\n"
163            "contents of the Schema Grammar. Essentially, shows how one can\n"
164            "access the Schema information stored in internal data structures.\n"
165         << XERCES_STD_QUALIFIER endl;
166}
167
168// ---------------------------------------------------------------------------
169//  Program entry point
170// ---------------------------------------------------------------------------
171int main(int argC, char* argV[])
172{
173    // cannot return out of catch-blocks lest exception-destruction
174    // result in calls to destroyed memory handler!
175    int errorCode = 0;
176    // Initialize the XML4C system
177    try
178    {
179         XMLPlatformUtils::Initialize();
180    }
181
182    catch (const XMLException& toCatch)
183    {
184         XERCES_STD_QUALIFIER cerr   << "Error during initialization! Message:\n"
185                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
186         errorCode = 1;
187    }
188    if(errorCode) {
189        XMLPlatformUtils::Terminate();
190        return errorCode;
191    }
192
193    // Check command line and extract arguments.
194    // We only have one required parameter, which is the file to process
195    if ((argC != 2) ||
196        (*(argV[1]) == '-'))
197    {
198        usage();
199        XMLPlatformUtils::Terminate();
200        return 2;
201    }
202
203    try
204    {
205                process(argV[1]);
206    }
207    catch (const OutOfMemoryException&)
208    {
209        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
210        errorCode = 5;
211    }
212    catch (const XMLException& e)
213    {
214        XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << argV[1] << "'\n"
215             << "Exception message is:  \n"
216             << StrX(e.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl;
217        errorCode = 3;
218    }
219
220    XMLPlatformUtils::Terminate();
221
222        return errorCode;
223}
224
225void process(char* const xmlFile)
226{
227    //
228    //  Create a Schema validator to be used for our validation work. Then create
229    //  a SAX parser object and pass it our validator. Then, according to what
230    //  we were told on the command line, set it to validate or not. He owns
231    //  the validator, so we have to allocate it.
232    //
233    SAXParser parser;
234    parser.setValidationScheme(SAXParser::Val_Always);
235    parser.setDoNamespaces(true);
236    parser.setDoSchema(true);
237
238        parser.parse(xmlFile);
239
240    if (parser.getErrorCount())
241        {
242        XERCES_STD_QUALIFIER cout << "\nErrors occurred, no output available\n" << XERCES_STD_QUALIFIER endl;
243                return;
244        }
245
246        if (!parser.getValidator().handlesSchema())
247        {
248                XERCES_STD_QUALIFIER cout << "\n Non schema document, no output available\n" << XERCES_STD_QUALIFIER endl;
249                return;
250        }
251
252        Grammar* rootGrammar = parser.getRootGrammar();
253        if (!rootGrammar || rootGrammar->getGrammarType() != Grammar::SchemaGrammarType)
254        {
255                XERCES_STD_QUALIFIER cout << "\n Non schema grammar, no output available\n" << XERCES_STD_QUALIFIER endl;
256                return;
257        }
258
259        //
260        //  Now we will get an enumerator for the element pool from the validator
261        //  and enumerate the elements, printing them as we go. For each element
262        //  we get an enumerator for its attributes and print them also.
263        //
264
265        SchemaGrammar* grammar = (SchemaGrammar*) rootGrammar;
266        RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
267
268        if (!elemEnum.hasMoreElements())
269        {
270                XERCES_STD_QUALIFIER cout << "\nThe validator has no elements to display\n" << XERCES_STD_QUALIFIER endl;
271                return;
272        }
273
274        while(elemEnum.hasMoreElements())
275        {
276                const SchemaElementDecl& curElem = elemEnum.nextElement();
277
278                // Name
279                XERCES_STD_QUALIFIER cout << "Name:\t\t\t" << StrX(curElem.getFullName()) << "\n";
280
281                // Model Type
282                XERCES_STD_QUALIFIER cout << "Model Type:\t\t";
283                switch( curElem.getModelType() )
284                {
285                case SchemaElementDecl::Empty:          XERCES_STD_QUALIFIER cout << "Empty";         break;
286                case SchemaElementDecl::Any:            XERCES_STD_QUALIFIER cout << "Any";           break;
287                case SchemaElementDecl::Mixed_Simple:   XERCES_STD_QUALIFIER cout << "Mixed_Simple";  break;
288                case SchemaElementDecl::Mixed_Complex:  XERCES_STD_QUALIFIER cout << "Mixed_Complex"; break;
289                case SchemaElementDecl::Children:       XERCES_STD_QUALIFIER cout << "Children";      break;
290                case SchemaElementDecl::Simple:         XERCES_STD_QUALIFIER cout << "Simple";        break;
291
292                default:                                XERCES_STD_QUALIFIER cout << "Unknown";       break;
293                }
294
295                XERCES_STD_QUALIFIER cout << "\n";
296
297                // Create Reason
298                XERCES_STD_QUALIFIER cout << "Create Reason:\t";
299                switch( curElem.getCreateReason() )
300                {
301                case XMLElementDecl::NoReason:          XERCES_STD_QUALIFIER cout << "Empty";            break;
302                case XMLElementDecl::Declared:          XERCES_STD_QUALIFIER cout << "Declared";         break;
303                case XMLElementDecl::AttList:           XERCES_STD_QUALIFIER cout << "AttList";          break;
304                case XMLElementDecl::InContentModel:    XERCES_STD_QUALIFIER cout << "InContentModel";   break;
305                case XMLElementDecl::AsRootElem:        XERCES_STD_QUALIFIER cout << "AsRootElem";       break;
306                case XMLElementDecl::JustFaultIn:       XERCES_STD_QUALIFIER cout << "JustFaultIn";      break;
307
308                default:                            XERCES_STD_QUALIFIER cout << "Unknown";  break;
309                }
310
311                XERCES_STD_QUALIFIER cout << "\n";
312
313                // Content Spec Node
314                processContentSpecNode( curElem.getContentSpec() );
315
316                // Misc Flags
317                int mflags = curElem.getMiscFlags();
318                if( mflags !=0 )
319                {
320                        XERCES_STD_QUALIFIER cout << "Misc. Flags:\t";
321                }
322
323        if ( mflags & SchemaSymbols::XSD_NILLABLE )
324                        XERCES_STD_QUALIFIER cout << "Nillable ";
325
326                if ( mflags & SchemaSymbols::XSD_ABSTRACT )
327                        XERCES_STD_QUALIFIER cout << "Abstract ";
328
329                if ( mflags & SchemaSymbols::XSD_FIXED )
330                        XERCES_STD_QUALIFIER cout << "Fixed ";
331
332                if( mflags !=0 )
333                {
334                        XERCES_STD_QUALIFIER cout << "\n";
335                }
336
337                // Substitution Name
338                SchemaElementDecl* subsGroup = curElem.getSubstitutionGroupElem();
339                if( subsGroup )
340                {
341                        const XMLCh* uriText = parser.getURIText(subsGroup->getURI());
342                        XERCES_STD_QUALIFIER cout << "Substitution Name:\t" << StrX(uriText)
343                             << "," << StrX(subsGroup->getBaseName()) << "\n";
344                }
345
346                // Content Model
347                const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
348                if( fmtCntModel != NULL )
349                {
350                        XERCES_STD_QUALIFIER cout << "Content Model:\t" << StrX(fmtCntModel) << "\n";
351                }
352
353                const ComplexTypeInfo* ctype = curElem.getComplexTypeInfo();
354                if( ctype != NULL)
355                {
356                        XERCES_STD_QUALIFIER cout << "ComplexType:\n";
357                        XERCES_STD_QUALIFIER cout << "\tTypeName:\t" << StrX(ctype->getTypeName()) << "\n";
358
359                        ContentSpecNode* cSpecNode = ctype->getContentSpec();
360                        processContentSpecNode(cSpecNode, true );
361                }
362
363                // Datatype
364                DatatypeValidator* dtValidator = curElem.getDatatypeValidator();
365                processDatatypeValidator( dtValidator );
366
367                // Get an enumerator for this guy's attributes if any
368                if ( curElem.hasAttDefs() )
369                {
370                        processAttributes( curElem.getAttDefList() );
371                }
372
373                XERCES_STD_QUALIFIER cout << "--------------------------------------------";
374                XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
375
376    }
377
378    return;
379}
380
381
382//---------------------------------------------------------------------
383//  Prints the Attribute's properties
384//---------------------------------------------------------------------
385void processAttributes( XMLAttDefList& attList, bool margin )
386{
387    if ( attList.isEmpty() )
388    {
389        return;
390    }
391
392    if ( margin )
393    {
394        XERCES_STD_QUALIFIER cout << "\t";
395    }
396
397    XERCES_STD_QUALIFIER cout << "Attributes:\n";
398    while( attList.hasMoreElements() )
399    {
400        // Name
401        SchemaAttDef& curAttDef = (SchemaAttDef&)attList.nextElement();
402        XERCES_STD_QUALIFIER cout << "\tName:\t\t\t" << StrX(curAttDef.getFullName()) << "\n";
403
404        // Type
405        XERCES_STD_QUALIFIER cout << "\tType:\t\t\t";
406                XERCES_STD_QUALIFIER cout << StrX(XMLAttDef::getAttTypeString(curAttDef.getType()));
407        XERCES_STD_QUALIFIER cout << "\n";
408
409        // Default Type
410        XERCES_STD_QUALIFIER cout << "\tDefault Type:\t";
411                XERCES_STD_QUALIFIER cout << StrX(XMLAttDef::getDefAttTypeString(curAttDef.getDefaultType()));
412        XERCES_STD_QUALIFIER cout << "\n";
413
414        // Value
415        if( curAttDef.getValue() )
416        {
417            XERCES_STD_QUALIFIER cout << "\tValue:\t\t\t";
418            XERCES_STD_QUALIFIER cout << StrX(curAttDef.getValue());
419            XERCES_STD_QUALIFIER cout << "\n";
420        }
421
422        // Enum. values
423        if( curAttDef.getEnumeration() )
424        {
425            XERCES_STD_QUALIFIER cout << "\tEnumeration:\t";
426            XERCES_STD_QUALIFIER cout << StrX(curAttDef.getEnumeration());
427            XERCES_STD_QUALIFIER cout << "\n";
428        }
429
430         const DatatypeValidator* dv = curAttDef.getDatatypeValidator();
431         processDatatypeValidator( dv, true );
432
433        XERCES_STD_QUALIFIER cout << "\n";
434    }
435}
436
437void processDatatypeValidator( const DatatypeValidator* dtValidator, bool margin )
438{
439    if( !dtValidator )
440    {
441        return;
442    }
443
444    if( margin )
445    {
446        XERCES_STD_QUALIFIER cout << "\t";
447    }
448
449    XERCES_STD_QUALIFIER cout << "Base Datatype:\t\t";
450    switch( dtValidator->getType() )
451    {
452    case DatatypeValidator::String:         XERCES_STD_QUALIFIER cout << "string";      break;
453    case DatatypeValidator::AnyURI:         XERCES_STD_QUALIFIER cout << "AnyURI";      break;
454    case DatatypeValidator::QName:          XERCES_STD_QUALIFIER cout << "QName";       break;
455        case DatatypeValidator::Name:           XERCES_STD_QUALIFIER cout << "Name";        break;
456        case DatatypeValidator::NCName:         XERCES_STD_QUALIFIER cout << "NCName";      break;
457    case DatatypeValidator::Boolean:        XERCES_STD_QUALIFIER cout << "Boolean";     break;
458    case DatatypeValidator::Float:          XERCES_STD_QUALIFIER cout << "Float";       break;
459    case DatatypeValidator::Double:         XERCES_STD_QUALIFIER cout << "Double";      break;
460    case DatatypeValidator::Decimal:        XERCES_STD_QUALIFIER cout << "Decimal";     break;
461    case DatatypeValidator::HexBinary:      XERCES_STD_QUALIFIER cout << "HexBinary";   break;
462    case DatatypeValidator::Base64Binary:   XERCES_STD_QUALIFIER cout << "Base64Binary";break;
463    case DatatypeValidator::Duration:       XERCES_STD_QUALIFIER cout << "Duration";    break;
464    case DatatypeValidator::DateTime:       XERCES_STD_QUALIFIER cout << "DateTime";    break;
465    case DatatypeValidator::Date:           XERCES_STD_QUALIFIER cout << "Date";        break;
466    case DatatypeValidator::Time:           XERCES_STD_QUALIFIER cout << "Time";        break;
467    case DatatypeValidator::MonthDay:       XERCES_STD_QUALIFIER cout << "MonthDay";    break;
468    case DatatypeValidator::YearMonth:      XERCES_STD_QUALIFIER cout << "YearMonth";   break;
469    case DatatypeValidator::Year:           XERCES_STD_QUALIFIER cout << "Year";        break;
470    case DatatypeValidator::Month:          XERCES_STD_QUALIFIER cout << "Month";       break;
471    case DatatypeValidator::Day:            XERCES_STD_QUALIFIER cout << "Day";         break;
472    case DatatypeValidator::ID:             XERCES_STD_QUALIFIER cout << "ID";          break;
473    case DatatypeValidator::IDREF:          XERCES_STD_QUALIFIER cout << "IDREF";       break;
474    case DatatypeValidator::ENTITY:         XERCES_STD_QUALIFIER cout << "ENTITY";      break;
475    case DatatypeValidator::NOTATION:       XERCES_STD_QUALIFIER cout << "NOTATION";    break;
476    case DatatypeValidator::List:           XERCES_STD_QUALIFIER cout << "List";        break;
477    case DatatypeValidator::Union:          XERCES_STD_QUALIFIER cout << "Union";       break;
478    case DatatypeValidator::AnySimpleType:  XERCES_STD_QUALIFIER cout << "AnySimpleType"; break;
479    }
480
481    XERCES_STD_QUALIFIER cout << "\n";
482
483    // Facets
484        RefHashTableOf<KVStringPair>* facets = dtValidator->getFacets();
485    if( facets )
486    {
487        RefHashTableOfEnumerator<KVStringPair> enumFacets(facets);
488        if( enumFacets.hasMoreElements() )
489        {
490            XERCES_STD_QUALIFIER cout << "Facets:\t\t\n";
491        }
492
493        while(enumFacets.hasMoreElements())
494        {
495            // Element's properties
496            const KVStringPair& curPair = enumFacets.nextElement();
497            XERCES_STD_QUALIFIER cout << "\t" << StrX( curPair.getKey() )    << "="
498                         << StrX( curPair.getValue() )  << "\n";
499        }
500    }
501
502        // Enumerations
503        RefVectorOf<XMLCh>* enums = (RefVectorOf<XMLCh>*) dtValidator->getEnumString();
504        if (enums)
505        {
506                XERCES_STD_QUALIFIER cout << "Enumeration:\t\t\n";
507
508        int enumLength = enums->size();
509        for ( int i = 0; i < enumLength; i++)
510        {
511            XERCES_STD_QUALIFIER cout << "\t" << StrX( enums->elementAt(i)) << "\n";
512        }
513
514        }
515}
516
517void processContentSpecNode( const ContentSpecNode* cSpecNode, bool margin )
518{
519    if( !cSpecNode )
520    {
521        return;
522    }
523
524    if( margin )
525    {
526        XERCES_STD_QUALIFIER cout << "\t";
527    }
528
529    XERCES_STD_QUALIFIER cout << "ContentType:\t";
530    switch( cSpecNode->getType() )
531    {
532        case ContentSpecNode::Leaf:             XERCES_STD_QUALIFIER cout << "Leaf";           break;
533        case ContentSpecNode::ZeroOrOne:        XERCES_STD_QUALIFIER cout << "ZeroOrOne";      break;
534        case ContentSpecNode::ZeroOrMore:       XERCES_STD_QUALIFIER cout << "ZeroOrMore";     break;
535        case ContentSpecNode::OneOrMore:        XERCES_STD_QUALIFIER cout << "OneOrMore";      break;
536        case ContentSpecNode::Choice:           XERCES_STD_QUALIFIER cout << "Choice";         break;
537        case ContentSpecNode::Sequence:         XERCES_STD_QUALIFIER cout << "Sequence";       break;
538                case ContentSpecNode::All:              XERCES_STD_QUALIFIER cout << "All";            break;
539        case ContentSpecNode::Any:              XERCES_STD_QUALIFIER cout << "Any";            break;
540        case ContentSpecNode::Any_Other:        XERCES_STD_QUALIFIER cout << "Any_Other";      break;
541        case ContentSpecNode::Any_NS:           XERCES_STD_QUALIFIER cout << "Any_NS";         break;
542        case ContentSpecNode::Any_Lax:          XERCES_STD_QUALIFIER cout << "Any_Lax";        break;
543        case ContentSpecNode::Any_Other_Lax:    XERCES_STD_QUALIFIER cout << "Any_Other_Lax";  break;
544        case ContentSpecNode::Any_NS_Lax:       XERCES_STD_QUALIFIER cout << "Any_NS_Lax";     break;
545        case ContentSpecNode::Any_Skip:         XERCES_STD_QUALIFIER cout << "Any_Skip";       break;
546        case ContentSpecNode::Any_Other_Skip:   XERCES_STD_QUALIFIER cout << "Any_Other_Skip"; break;
547        case ContentSpecNode::Any_NS_Skip:      XERCES_STD_QUALIFIER cout << "Any_NS_Skip";    break;
548        case ContentSpecNode::UnknownType:      XERCES_STD_QUALIFIER cout << "UnknownType";    break;
549    }
550    XERCES_STD_QUALIFIER cout << "\n";
551}
552
Note: See TracBrowser for help on using the repository browser.