source: icXML/icXML-devel/samples/src/SEnumVal/SEnumVal.cpp @ 2726

Last change on this file since 2726 was 2726, checked in by cameron, 6 years ago

Add original Xerces tests and samples directories

File size: 19.5 KB
Line 
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: SEnumVal.cpp 933155 2010-04-12 09:07:02Z amassari $
20 */
21// ---------------------------------------------------------------------------
22//  Includes
23// ---------------------------------------------------------------------------
24#include <xercesc/util/NameIdPool.hpp>
25#include <xercesc/util/PlatformUtils.hpp>
26#include <xercesc/framework/XMLValidator.hpp>
27#include <xercesc/framework/psvi/XSAnnotation.hpp>
28#include <xercesc/parsers/SAXParser.hpp>
29#include <xercesc/validators/schema/SchemaValidator.hpp>
30#include <xercesc/validators/schema/SchemaSymbols.hpp>
31#include <xercesc/validators/common/ContentSpecNode.hpp>
32#include <xercesc/util/OutOfMemoryException.hpp>
33#if defined(XERCES_NEW_IOSTREAMS)
34#include <iostream>
35#else
36#include <iostream.h>
37#endif
38#include <stdlib.h>
39#include <string.h>
40
41
42XERCES_CPP_NAMESPACE_USE
43
44// ---------------------------------------------------------------------------
45//  Forward references
46// ---------------------------------------------------------------------------
47static void usage();
48
49void process(char* const);
50void processAttributes( XMLAttDefList& attList, bool margin = false );
51void processDatatypeValidator( const DatatypeValidator*, bool margin = false
52);
53void processContentSpecNode( const ContentSpecNode* specNode, bool margin =
54false );
55
56// ---------------------------------------------------------------------------
57//  This is a simple class that lets us do easy (though not terribly efficient)
58//  trancoding of XMLCh data to local code page for display.
59// ---------------------------------------------------------------------------
60class StrX
61{
62public :
63    // -----------------------------------------------------------------------
64    //  Constructors and Destructor
65    // -----------------------------------------------------------------------
66    StrX(const XMLCh* const toTranscode)
67    {
68        // Call the private transcoding method
69        fLocalForm = XMLString::transcode(toTranscode);
70    }
71
72    ~StrX()
73    {
74        XMLString::release(&fLocalForm);
75    }
76
77
78    // -----------------------------------------------------------------------
79    //  Getter methods
80    // -----------------------------------------------------------------------
81    const char* localForm() const
82    {
83        return fLocalForm;
84    }
85
86private :
87    // -----------------------------------------------------------------------
88    //  Private data members
89    //
90    //  fLocalForm
91    //      This is the local code page form of the string.
92    // -----------------------------------------------------------------------
93    char*   fLocalForm;
94};
95
96inline XERCES_STD_QUALIFIER ostream& operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)
97{
98    target << toDump.localForm();
99    return target;
100}
101
102// ---------------------------------------------------------------------------
103//  Local helper methods
104// ---------------------------------------------------------------------------
105static void usage()
106{
107    XERCES_STD_QUALIFIER cout << "\nUsage:\n"
108            "    SEnumVal <XML file>\n\n"
109            "This program parses a file, then shows how to enumerate the\n"
110            "contents of the Schema Grammar. Essentially, shows how one can\n"
111            "access the Schema information stored in internal data structures.\n"
112         << XERCES_STD_QUALIFIER endl;
113}
114
115// ---------------------------------------------------------------------------
116//  Program entry point
117// ---------------------------------------------------------------------------
118int main(int argC, char* argV[])
119{
120    // cannot return out of catch-blocks lest exception-destruction
121    // result in calls to destroyed memory handler!
122    int errorCode = 0;
123    // Initialize the XML4C system
124    try
125    {
126         XMLPlatformUtils::Initialize();
127    }
128
129    catch (const XMLException& toCatch)
130    {
131         XERCES_STD_QUALIFIER cerr   << "Error during initialization! Message:\n"
132                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
133         errorCode = 1;
134    }
135    if(errorCode) {
136        XMLPlatformUtils::Terminate();
137        return errorCode;
138    } 
139
140    // Check command line and extract arguments.
141    // We only have one required parameter, which is the file to process
142    if ((argC != 2) ||
143        (*(argV[1]) == '-'))
144    {
145        usage();
146        XMLPlatformUtils::Terminate();
147        return 2;
148    }
149
150    try
151    {
152                process(argV[1]);
153    }
154    catch (const OutOfMemoryException&)
155    {
156        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
157        errorCode = 5;
158    }
159    catch (const XMLException& e)
160    {
161        XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << argV[1] << "'\n"
162             << "Exception message is:  \n"
163             << StrX(e.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl;
164        errorCode = 3;
165    }
166
167    XMLPlatformUtils::Terminate();
168
169        return errorCode;
170}
171
172void process(char* const xmlFile)
173{
174    //
175    //  Create a Schema validator to be used for our validation work. Then create
176    //  a SAX parser object and pass it our validator. Then, according to what
177    //  we were told on the command line, set it to validate or not. He owns
178    //  the validator, so we have to allocate it.
179    //
180    SAXParser parser;
181    parser.setValidationScheme(SAXParser::Val_Always);
182    parser.setDoNamespaces(true);
183    parser.setDoSchema(true);
184
185        parser.parse(xmlFile);
186
187    if (parser.getErrorCount())
188        {
189        XERCES_STD_QUALIFIER cout << "\nErrors occurred, no output available\n" << XERCES_STD_QUALIFIER endl;
190                return;
191        }
192
193        if (!parser.getValidator().handlesSchema())
194        {
195                XERCES_STD_QUALIFIER cout << "\n Non schema document, no output available\n" << XERCES_STD_QUALIFIER endl;
196                return;
197        }
198
199        Grammar* rootGrammar = parser.getRootGrammar();
200        if (!rootGrammar || rootGrammar->getGrammarType() != Grammar::SchemaGrammarType)
201        {
202                XERCES_STD_QUALIFIER cout << "\n Non schema grammar, no output available\n" << XERCES_STD_QUALIFIER endl;
203                return;
204        }
205
206        //
207        //  Now we will get an enumerator for the element pool from the validator
208        //  and enumerate the elements, printing them as we go. For each element
209        //  we get an enumerator for its attributes and print them also.
210        //
211
212        SchemaGrammar* grammar = (SchemaGrammar*) rootGrammar;
213        RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
214
215        if (!elemEnum.hasMoreElements())
216        {
217                XERCES_STD_QUALIFIER cout << "\nThe validator has no elements to display\n" << XERCES_STD_QUALIFIER endl;
218                return;
219        }
220
221        while(elemEnum.hasMoreElements())
222        {
223                const SchemaElementDecl& curElem = elemEnum.nextElement();
224
225                // Name
226                XERCES_STD_QUALIFIER cout << "Name:\t\t\t" << StrX(curElem.getFullName()) << "\n";
227
228                // Model Type
229                XERCES_STD_QUALIFIER cout << "Model Type:\t\t";
230                switch( curElem.getModelType() )
231                {
232                case SchemaElementDecl::Empty:          XERCES_STD_QUALIFIER cout << "Empty";         break;
233                case SchemaElementDecl::Any:            XERCES_STD_QUALIFIER cout << "Any";           break;
234                case SchemaElementDecl::Mixed_Simple:   XERCES_STD_QUALIFIER cout << "Mixed_Simple";  break;
235                case SchemaElementDecl::Mixed_Complex:  XERCES_STD_QUALIFIER cout << "Mixed_Complex"; break;
236                case SchemaElementDecl::Children:       XERCES_STD_QUALIFIER cout << "Children";      break;
237                case SchemaElementDecl::Simple:         XERCES_STD_QUALIFIER cout << "Simple";        break;
238        case SchemaElementDecl::ElementOnlyEmpty:    XERCES_STD_QUALIFIER cout << "ElementOnlyEmpty";    break;
239
240                default:                                XERCES_STD_QUALIFIER cout << "Unknown";       break;
241                }
242
243                XERCES_STD_QUALIFIER cout << "\n";
244
245                // Create Reason
246                XERCES_STD_QUALIFIER cout << "Create Reason:\t";
247                switch( curElem.getCreateReason() )
248                {
249                case XMLElementDecl::NoReason:          XERCES_STD_QUALIFIER cout << "Empty";            break;
250                case XMLElementDecl::Declared:          XERCES_STD_QUALIFIER cout << "Declared";         break;
251                case XMLElementDecl::AttList:           XERCES_STD_QUALIFIER cout << "AttList";          break;
252                case XMLElementDecl::InContentModel:    XERCES_STD_QUALIFIER cout << "InContentModel";   break;
253                case XMLElementDecl::AsRootElem:        XERCES_STD_QUALIFIER cout << "AsRootElem";       break;
254                case XMLElementDecl::JustFaultIn:       XERCES_STD_QUALIFIER cout << "JustFaultIn";      break;
255
256                default:                            XERCES_STD_QUALIFIER cout << "Unknown";  break;
257                }
258
259                XERCES_STD_QUALIFIER cout << "\n";
260
261                // Content Spec Node
262                processContentSpecNode( curElem.getContentSpec() );
263
264                // Misc Flags
265                int mflags = curElem.getMiscFlags();
266                if( mflags !=0 )
267                {
268                        XERCES_STD_QUALIFIER cout << "Misc. Flags:\t";
269                }
270
271        if ( mflags & SchemaSymbols::XSD_NILLABLE )
272                        XERCES_STD_QUALIFIER cout << "Nillable ";
273
274                if ( mflags & SchemaSymbols::XSD_ABSTRACT )
275                        XERCES_STD_QUALIFIER cout << "Abstract ";
276
277                if ( mflags & SchemaSymbols::XSD_FIXED )
278                        XERCES_STD_QUALIFIER cout << "Fixed ";
279
280                if( mflags !=0 )
281                {
282                        XERCES_STD_QUALIFIER cout << "\n";
283                }
284
285                // Substitution Name
286                SchemaElementDecl* subsGroup = curElem.getSubstitutionGroupElem();
287                if( subsGroup )
288                {
289                        const XMLCh* uriText = parser.getURIText(subsGroup->getURI());
290                        XERCES_STD_QUALIFIER cout << "Substitution Name:\t" << StrX(uriText)
291                             << "," << StrX(subsGroup->getBaseName()) << "\n";
292                }
293
294                // Content Model
295                const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
296                if( fmtCntModel != NULL )
297                {
298                        XERCES_STD_QUALIFIER cout << "Content Model:\t" << StrX(fmtCntModel) << "\n";
299                }
300
301                const ComplexTypeInfo* ctype = curElem.getComplexTypeInfo();
302                if( ctype != NULL)
303                {
304                        XERCES_STD_QUALIFIER cout << "ComplexType:\n";
305                        XERCES_STD_QUALIFIER cout << "\tTypeName:\t" << StrX(ctype->getTypeName()) << "\n";
306
307                        ContentSpecNode* cSpecNode = ctype->getContentSpec();
308                        processContentSpecNode(cSpecNode, true );
309                }
310
311                // Datatype
312                DatatypeValidator* dtValidator = curElem.getDatatypeValidator();
313                processDatatypeValidator( dtValidator );
314
315                // Get an enumerator for this guy's attributes if any
316                if ( curElem.hasAttDefs() )
317                {
318                        processAttributes( curElem.getAttDefList() );
319                }
320
321                XERCES_STD_QUALIFIER cout << "--------------------------------------------";
322                XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;
323
324    }
325
326    return;
327}
328
329
330//---------------------------------------------------------------------
331//  Prints the Attribute's properties
332//---------------------------------------------------------------------
333void processAttributes( XMLAttDefList& attList, bool margin )
334{
335    if ( attList.isEmpty() )
336    {
337        return;
338    }
339
340    if ( margin )
341    {
342        XERCES_STD_QUALIFIER cout << "\t";
343    }
344
345    XERCES_STD_QUALIFIER cout << "Attributes:\n";
346    for (unsigned int i=0; i<attList.getAttDefCount(); i++)
347    {
348        // Name
349        SchemaAttDef& curAttDef = (SchemaAttDef&)attList.getAttDef(i);
350        XERCES_STD_QUALIFIER cout << "\tName:\t\t\t" << StrX(curAttDef.getFullName()) << "\n";
351
352        // Type
353        XERCES_STD_QUALIFIER cout << "\tType:\t\t\t";
354                XERCES_STD_QUALIFIER cout << StrX(XMLAttDef::getAttTypeString(curAttDef.getType()));
355        XERCES_STD_QUALIFIER cout << "\n";
356
357        // Default Type
358        XERCES_STD_QUALIFIER cout << "\tDefault Type:\t";
359                XERCES_STD_QUALIFIER cout << StrX(XMLAttDef::getDefAttTypeString(curAttDef.getDefaultType()));
360        XERCES_STD_QUALIFIER cout << "\n";
361
362        // Value
363        if( curAttDef.getValue() )
364        {
365            XERCES_STD_QUALIFIER cout << "\tValue:\t\t\t";
366            XERCES_STD_QUALIFIER cout << StrX(curAttDef.getValue());
367            XERCES_STD_QUALIFIER cout << "\n";
368        }
369
370        // Enum. values
371        if( curAttDef.getEnumeration() )
372        {
373            XERCES_STD_QUALIFIER cout << "\tEnumeration:\t";
374            XERCES_STD_QUALIFIER cout << StrX(curAttDef.getEnumeration());
375            XERCES_STD_QUALIFIER cout << "\n";
376        }
377
378         const DatatypeValidator* dv = curAttDef.getDatatypeValidator();
379         processDatatypeValidator( dv, true );
380
381        XERCES_STD_QUALIFIER cout << "\n";
382    }
383}
384
385void processDatatypeValidator( const DatatypeValidator* dtValidator, bool margin )
386{
387    if( !dtValidator )
388    {
389        return;
390    }
391
392    if( margin )
393    {
394        XERCES_STD_QUALIFIER cout << "\t";
395    }
396
397    XERCES_STD_QUALIFIER cout << "Base Datatype:\t\t";
398    switch( dtValidator->getType() )
399    {
400    case DatatypeValidator::String:         XERCES_STD_QUALIFIER cout << "string";      break;
401    case DatatypeValidator::AnyURI:         XERCES_STD_QUALIFIER cout << "AnyURI";      break;
402    case DatatypeValidator::QName:          XERCES_STD_QUALIFIER cout << "QName";       break;
403    case DatatypeValidator::Name:           XERCES_STD_QUALIFIER cout << "Name";        break;
404    case DatatypeValidator::NCName:         XERCES_STD_QUALIFIER cout << "NCName";      break;
405    case DatatypeValidator::Boolean:        XERCES_STD_QUALIFIER cout << "Boolean";     break;
406    case DatatypeValidator::Float:          XERCES_STD_QUALIFIER cout << "Float";       break;
407    case DatatypeValidator::Double:         XERCES_STD_QUALIFIER cout << "Double";      break;
408    case DatatypeValidator::Decimal:        XERCES_STD_QUALIFIER cout << "Decimal";     break;
409    case DatatypeValidator::HexBinary:      XERCES_STD_QUALIFIER cout << "HexBinary";   break;
410    case DatatypeValidator::Base64Binary:   XERCES_STD_QUALIFIER cout << "Base64Binary";break;
411    case DatatypeValidator::Duration:       XERCES_STD_QUALIFIER cout << "Duration";    break;
412    case DatatypeValidator::DateTime:       XERCES_STD_QUALIFIER cout << "DateTime";    break;
413    case DatatypeValidator::Date:           XERCES_STD_QUALIFIER cout << "Date";        break;
414    case DatatypeValidator::Time:           XERCES_STD_QUALIFIER cout << "Time";        break;
415    case DatatypeValidator::MonthDay:       XERCES_STD_QUALIFIER cout << "MonthDay";    break;
416    case DatatypeValidator::YearMonth:      XERCES_STD_QUALIFIER cout << "YearMonth";   break;
417    case DatatypeValidator::Year:           XERCES_STD_QUALIFIER cout << "Year";        break;
418    case DatatypeValidator::Month:          XERCES_STD_QUALIFIER cout << "Month";       break;
419    case DatatypeValidator::Day:            XERCES_STD_QUALIFIER cout << "Day";         break;
420    case DatatypeValidator::ID:             XERCES_STD_QUALIFIER cout << "ID";          break;
421    case DatatypeValidator::IDREF:          XERCES_STD_QUALIFIER cout << "IDREF";       break;
422    case DatatypeValidator::ENTITY:         XERCES_STD_QUALIFIER cout << "ENTITY";      break;
423    case DatatypeValidator::NOTATION:       XERCES_STD_QUALIFIER cout << "NOTATION";    break;
424    case DatatypeValidator::List:           XERCES_STD_QUALIFIER cout << "List";        break;
425    case DatatypeValidator::Union:          XERCES_STD_QUALIFIER cout << "Union";       break;
426    case DatatypeValidator::AnySimpleType:  XERCES_STD_QUALIFIER cout << "AnySimpleType"; break;
427    case DatatypeValidator::UnKnown:        XERCES_STD_QUALIFIER cout << "UNKNOWN";     break;
428    }
429
430    XERCES_STD_QUALIFIER cout << "\n";
431
432    // Facets
433        RefHashTableOf<KVStringPair>* facets = dtValidator->getFacets();
434    if( facets && facets->getCount()>0)
435    {
436        XMLSize_t i;
437        // Element's properties
438        XERCES_STD_QUALIFIER cout << "Facets:\t\t\n";
439        // use a list to print them sorted, or the list could be different on 64-bit machines
440        RefVectorOf<XMLCh> sortedList(facets->getCount(), false);
441        RefHashTableOfEnumerator<KVStringPair> enumFacets(facets);
442        while( enumFacets.hasMoreElements() )
443        {
444            const KVStringPair& curPair = enumFacets.nextElement();
445            const XMLCh* key=curPair.getKey();
446            XMLSize_t len=sortedList.size();
447            for(i=0;i<len;i++)
448                if(XMLString::compareString(key, sortedList.elementAt(i))<0)
449                {
450                    sortedList.insertElementAt((XMLCh*)key,i);
451                    break;
452                }
453            if(i==len)
454                sortedList.addElement((XMLCh*)key);
455        }
456
457        XMLSize_t len=sortedList.size();
458        for(i=0;i<len;i++)
459        {
460            const XMLCh* key = sortedList.elementAt(i);
461            XERCES_STD_QUALIFIER cout << "\t" << StrX( key )    << "="
462                         << StrX( facets->get(key)->getValue() )  << "\n";
463        }
464    }
465
466        // Enumerations
467        RefVectorOf<XMLCh>* enums = (RefVectorOf<XMLCh>*) dtValidator->getEnumString();
468        if (enums)
469        {
470                XERCES_STD_QUALIFIER cout << "Enumeration:\t\t\n";
471
472        int enumLength = enums->size();
473        for ( int i = 0; i < enumLength; i++)
474        {
475            XERCES_STD_QUALIFIER cout << "\t" << StrX( enums->elementAt(i)) << "\n";
476        }
477
478        }
479}
480
481void processContentSpecNode( const ContentSpecNode* cSpecNode, bool margin )
482{
483    if( !cSpecNode )
484    {
485        return;
486    }
487
488    if( margin )
489    {
490        XERCES_STD_QUALIFIER cout << "\t";
491    }
492
493    XERCES_STD_QUALIFIER cout << "ContentType:\t";
494    switch( cSpecNode->getType() )
495    {
496        case ContentSpecNode::Leaf:                XERCES_STD_QUALIFIER cout << "Leaf";           break;
497        case ContentSpecNode::ZeroOrOne:           XERCES_STD_QUALIFIER cout << "ZeroOrOne";      break;
498        case ContentSpecNode::ZeroOrMore:          XERCES_STD_QUALIFIER cout << "ZeroOrMore";     break;
499        case ContentSpecNode::OneOrMore:           XERCES_STD_QUALIFIER cout << "OneOrMore";      break;
500        case ContentSpecNode::ModelGroupChoice:   
501        case ContentSpecNode::Choice:              XERCES_STD_QUALIFIER cout << "Choice";         break;
502        case ContentSpecNode::ModelGroupSequence: 
503        case ContentSpecNode::Sequence:            XERCES_STD_QUALIFIER cout << "Sequence";       break;
504        case ContentSpecNode::All:                 XERCES_STD_QUALIFIER cout << "All";            break;
505        case ContentSpecNode::Any:                 XERCES_STD_QUALIFIER cout << "Any";            break;
506        case ContentSpecNode::Any_Other:           XERCES_STD_QUALIFIER cout << "Any_Other";      break;
507        case ContentSpecNode::Any_NS:              XERCES_STD_QUALIFIER cout << "Any_NS";         break;
508        case ContentSpecNode::Any_Lax:             XERCES_STD_QUALIFIER cout << "Any_Lax";        break;
509        case ContentSpecNode::Any_Other_Lax:       XERCES_STD_QUALIFIER cout << "Any_Other_Lax";  break;
510        case ContentSpecNode::Any_NS_Lax:          XERCES_STD_QUALIFIER cout << "Any_NS_Lax";     break;
511        case ContentSpecNode::Any_Skip:            XERCES_STD_QUALIFIER cout << "Any_Skip";       break;
512        case ContentSpecNode::Any_Other_Skip:      XERCES_STD_QUALIFIER cout << "Any_Other_Skip"; break;
513        case ContentSpecNode::Any_NS_Skip:         XERCES_STD_QUALIFIER cout << "Any_NS_Skip";    break;
514        case ContentSpecNode::Any_NS_Choice:       XERCES_STD_QUALIFIER cout << "Any_NS_Choice";  break;
515        case ContentSpecNode::UnknownType:         XERCES_STD_QUALIFIER cout << "UnknownType";    break;
516    }
517    XERCES_STD_QUALIFIER cout << "\n";
518}
519
Note: See TracBrowser for help on using the repository browser.