SEnumVal.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:19k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: SEnumVal.cpp,v 1.15 2003/02/05 18:53:24 tng Exp $
  58.  * $Log: SEnumVal.cpp,v $
  59.  * Revision 1.15  2003/02/05 18:53:24  tng
  60.  * [Bug 11915] Utility for freeing memory.
  61.  *
  62.  * Revision 1.14  2003/01/14 15:32:45  knoaman
  63.  * [Bug 16024] SchemaSymbols.hpp conflicts C++ Builder 6 dir.h
  64.  *
  65.  * Revision 1.13  2002/11/05 21:46:20  tng
  66.  * Explicit code using namespace in application.
  67.  *
  68.  * Revision 1.12  2002/07/12 15:51:52  knoaman
  69.  * Retrieve the root grammar instead of using the validator.
  70.  * Modify the way we print substitution group info.
  71.  *
  72.  * Revision 1.11  2002/06/25 15:30:46  peiyongz
  73.  * Bug#10067: SEnumVal bugs found when porting to Visual Studio .NET
  74.  *                     projects, patch from Robert Buck (rbuck@mathworks.com )
  75.  *
  76.  * Revision 1.10  2002/05/08 18:18:46  knoaman
  77.  * Fix bor bug 8301: INFINITY used as enum member.
  78.  *
  79.  * Revision 1.9  2002/04/17 20:18:08  tng
  80.  * [Bug 7493] The word "occured" is misspelled and it is a global error.
  81.  *
  82.  * Revision 1.8  2002/02/20 20:30:11  peiyongz
  83.  * Make the code compilable on Solaris 2.6's CC
  84.  *
  85.  * Revision 1.7  2002/02/14 15:14:58  peiyongz
  86.  * getEnumString()
  87.  *
  88.  * Revision 1.6  2002/02/01 22:41:28  peiyongz
  89.  * sane_include
  90.  *
  91.  * Revision 1.5  2001/11/22 14:47:48  tng
  92.  * Use the phrase "Grammar" instead of "Validator" in EnumVal and SEnumVal Description.
  93.  *
  94.  * Revision 1.4  2001/11/21 22:09:49  peiyongz
  95.  * Copy Right date
  96.  *
  97.  * Revision 1.3  2001/11/21 19:05:23  peiyongz
  98.  * SEnumVal: GrammarType checked
  99.  *
  100.  *
  101.  */
  102. // ---------------------------------------------------------------------------
  103. //  Includes
  104. // ---------------------------------------------------------------------------
  105. #include <xercesc/util/NameIdPool.hpp>
  106. #include <xercesc/util/PlatformUtils.hpp>
  107. #include <xercesc/framework/XMLValidator.hpp>
  108. #include <xercesc/parsers/SAXParser.hpp>
  109. #include <xercesc/validators/schema/SchemaValidator.hpp>
  110. #include <xercesc/validators/common/ContentSpecNode.hpp>
  111. #include <xercesc/validators/schema/SchemaSymbols.hpp>
  112. #include <iostream.h>
  113. #include <stdlib.h>
  114. #include <string.h>
  115. XERCES_CPP_NAMESPACE_USE
  116. // ---------------------------------------------------------------------------
  117. //  Forward references
  118. // ---------------------------------------------------------------------------
  119. static void usage();
  120. void process(char* const);
  121. void processAttributes( XMLAttDefList& attList, bool margin = false );
  122. void processDatatypeValidator( const DatatypeValidator*, bool margin = false
  123. );
  124. void processContentSpecNode( const ContentSpecNode* specNode, bool margin =
  125. false );
  126. // ---------------------------------------------------------------------------
  127. //  This is a simple class that lets us do easy (though not terribly efficient)
  128. //  trancoding of XMLCh data to local code page for display.
  129. // ---------------------------------------------------------------------------
  130. class StrX
  131. {
  132. public :
  133.     // -----------------------------------------------------------------------
  134.     //  Constructors and Destructor
  135.     // -----------------------------------------------------------------------
  136.     StrX(const XMLCh* const toTranscode)
  137.     {
  138.         // Call the private transcoding method
  139.         fLocalForm = XMLString::transcode(toTranscode);
  140.     }
  141.     ~StrX()
  142.     {
  143.         XMLString::release(&fLocalForm);
  144.     }
  145.     // -----------------------------------------------------------------------
  146.     //  Getter methods
  147.     // -----------------------------------------------------------------------
  148.     const char* localForm() const
  149.     {
  150.         return fLocalForm;
  151.     }
  152. private :
  153.     // -----------------------------------------------------------------------
  154.     //  Private data members
  155.     //
  156.     //  fLocalForm
  157.     //      This is the local code page form of the string.
  158.     // -----------------------------------------------------------------------
  159.     char*   fLocalForm;
  160. };
  161. inline ostream& operator<<(ostream& target, const StrX& toDump)
  162. {
  163.     target << toDump.localForm();
  164.     return target;
  165. }
  166. // ---------------------------------------------------------------------------
  167. //  Local helper methods
  168. // ---------------------------------------------------------------------------
  169. static void usage()
  170. {
  171.     cout << "nUsage:n"
  172.             "    SEnumVal <XML file>nn"
  173.             "This program parses a file, then shows how to enumerate then"
  174.             "contents of the Schema Grammar. Essentially, shows how one cann"
  175.             "access the Schema information stored in internal data structures.n"
  176.          << endl;
  177. }
  178. // ---------------------------------------------------------------------------
  179. //  Program entry point
  180. // ---------------------------------------------------------------------------
  181. int main(int argC, char* argV[])
  182. {
  183.     // Initialize the XML4C system
  184.     try
  185.     {
  186.          XMLPlatformUtils::Initialize();
  187.     }
  188.     catch (const XMLException& toCatch)
  189.     {
  190.          cerr   << "Error during initialization! Message:n"
  191.                 << StrX(toCatch.getMessage()) << endl;
  192.          XMLPlatformUtils::Terminate();
  193.          return 1;
  194.     }
  195.     // Check command line and extract arguments.
  196.     // We only have one required parameter, which is the file to process
  197.     if ((argC != 2) ||
  198.         (*(argV[1]) == '-'))
  199.     {
  200.         usage();
  201.         XMLPlatformUtils::Terminate();
  202.         return 2;
  203.     }
  204.     try
  205.     {
  206. process(argV[1]);
  207.     }
  208.     catch (const XMLException& e)
  209.     {
  210.         cerr << "nError during parsing: '" << argV[1] << "'n"
  211.              << "Exception message is:  n"
  212.              << StrX(e.getMessage()) << "n" << endl;
  213.         XMLPlatformUtils::Terminate();
  214.         return 3;
  215.     }
  216.     XMLPlatformUtils::Terminate();
  217. return 0;
  218. }
  219. void process(char* const xmlFile)
  220. {
  221.     //
  222.     //  Create a Schema validator to be used for our validation work. Then create
  223.     //  a SAX parser object and pass it our validator. Then, according to what
  224.     //  we were told on the command line, set it to validate or not. He owns
  225.     //  the validator, so we have to allocate it.
  226.     //
  227.     SAXParser parser;
  228.     parser.setValidationScheme(SAXParser::Val_Always);
  229.     parser.setDoNamespaces(true);
  230.     parser.setDoSchema(true);
  231. parser.parse(xmlFile);
  232.     if (parser.getErrorCount())
  233. {
  234.         cout << "nErrors occurred, no output availablen" << endl;
  235. return;
  236. }
  237. if (!parser.getValidator().handlesSchema())
  238. {
  239. cout << "n Non schema document, no output availablen" << endl;
  240. return;
  241. }
  242. Grammar* rootGrammar = parser.getRootGrammar();
  243. if (!rootGrammar || rootGrammar->getGrammarType() != Grammar::SchemaGrammarType)
  244. {
  245. cout << "n Non schema grammar, no output availablen" << endl;
  246. return;
  247. }
  248. //
  249. //  Now we will get an enumerator for the element pool from the validator
  250. //  and enumerate the elements, printing them as we go. For each element
  251. //  we get an enumerator for its attributes and print them also.
  252. //
  253. SchemaGrammar* grammar = (SchemaGrammar*) rootGrammar;
  254. RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
  255. if (!elemEnum.hasMoreElements())
  256. {
  257. cout << "nThe validator has no elements to displayn" << endl;
  258. return;
  259. }
  260. while(elemEnum.hasMoreElements())
  261. {
  262. const SchemaElementDecl& curElem = elemEnum.nextElement();
  263. // Name
  264. cout << "Name:ttt" << StrX(curElem.getFullName()) << "n";
  265. // Model Type
  266. cout << "Model Type:tt";
  267. switch( curElem.getModelType() )
  268. {
  269. case SchemaElementDecl::Empty:          cout << "Empty";         break;
  270. case SchemaElementDecl::Any:            cout << "Any";           break;
  271. case SchemaElementDecl::Mixed_Simple:   cout << "Mixed_Simple";  break;
  272. case SchemaElementDecl::Mixed_Complex:  cout << "Mixed_Complex"; break;
  273. case SchemaElementDecl::Children:       cout << "Children";      break;
  274. case SchemaElementDecl::Simple:         cout << "Simple";        break;
  275. default:                                cout << "Unknown";       break;
  276. }
  277. cout << "n";
  278. // Create Reason
  279. cout << "Create Reason:t";
  280. switch( curElem.getCreateReason() )
  281. {
  282. case XMLElementDecl::NoReason:          cout << "Empty";            break;
  283. case XMLElementDecl::Declared:          cout << "Declared";         break;
  284. case XMLElementDecl::AttList:           cout << "AttList";          break;
  285. case XMLElementDecl::InContentModel:    cout << "InContentModel";   break;
  286. case XMLElementDecl::AsRootElem:        cout << "AsRootElem";       break;
  287. case XMLElementDecl::JustFaultIn:       cout << "JustFaultIn";      break;
  288. default:                            cout << "Unknown";  break;
  289. }
  290. cout << "n";
  291. // Content Spec Node
  292. processContentSpecNode( curElem.getContentSpec() );
  293. // Misc Flags
  294. int mflags = curElem.getMiscFlags();
  295. if( mflags !=0 )
  296. {
  297. cout << "Misc. Flags:t";
  298. }
  299.         if ( mflags & SchemaSymbols::XSD_NILLABLE )
  300. cout << "Nillable ";
  301. if ( mflags & SchemaSymbols::XSD_ABSTRACT )
  302. cout << "Abstract ";
  303. if ( mflags & SchemaSymbols::XSD_FIXED )
  304. cout << "Fixed ";
  305. if( mflags !=0 )
  306. {
  307. cout << "n";
  308. }
  309. // Substitution Name
  310. SchemaElementDecl* subsGroup = curElem.getSubstitutionGroupElem();
  311. if( subsGroup )
  312. {
  313. const XMLCh* uriText = parser.getURIText(subsGroup->getURI());
  314. cout << "Substitution Name:t" << StrX(uriText)
  315.      << "," << StrX(subsGroup->getBaseName()) << "n";
  316. }
  317. // Content Model
  318. const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
  319. if( fmtCntModel != NULL )
  320. {
  321. cout << "Content Model:t" << StrX(fmtCntModel) << "n";
  322. }
  323. const ComplexTypeInfo* ctype = curElem.getComplexTypeInfo();
  324. if( ctype != NULL)
  325. {
  326. cout << "ComplexType:n";
  327. cout << "tTypeName:t" << StrX(ctype->getTypeName()) << "n";
  328. ContentSpecNode* cSpecNode = ctype->getContentSpec();
  329. processContentSpecNode(cSpecNode, true );
  330. }
  331. // Datatype
  332. DatatypeValidator* dtValidator = curElem.getDatatypeValidator();
  333. processDatatypeValidator( dtValidator );
  334. // Get an enumerator for this guy's attributes if any
  335. if ( curElem.hasAttDefs() )
  336. {
  337. processAttributes( curElem.getAttDefList() );
  338. }
  339. cout << "--------------------------------------------";
  340. cout << endl;
  341.     }
  342.     return;
  343. }
  344. //---------------------------------------------------------------------
  345. //  Prints the Attribute's properties
  346. //---------------------------------------------------------------------
  347. void processAttributes( XMLAttDefList& attList, bool margin )
  348. {
  349.     if ( attList.isEmpty() )
  350.     {
  351.         return;
  352.     }
  353.     if ( margin )
  354.     {
  355.         cout << "t";
  356.     }
  357.     cout << "Attributes:n";
  358.     while( attList.hasMoreElements() )
  359.     {
  360.         // Name
  361.         SchemaAttDef& curAttDef = (SchemaAttDef&)attList.nextElement();
  362.         cout << "tName:ttt" << StrX(curAttDef.getFullName()) << "n";
  363.         // Type
  364.         cout << "tType:ttt";
  365. cout << StrX(XMLAttDef::getAttTypeString(curAttDef.getType()));
  366.         cout << "n";
  367.         // Default Type
  368.         cout << "tDefault Type:t";
  369. cout << StrX(XMLAttDef::getDefAttTypeString(curAttDef.getDefaultType()));
  370.         cout << "n";
  371.         // Value
  372.         if( curAttDef.getValue() )
  373.         {
  374.             cout << "tValue:ttt";
  375.             cout << StrX(curAttDef.getValue());
  376.             cout << "n";
  377.         }
  378.         // Enum. values
  379.         if( curAttDef.getEnumeration() )
  380.         {
  381.             cout << "tEnumeration:t";
  382.             cout << StrX(curAttDef.getEnumeration());
  383.             cout << "n";
  384.         }
  385.          const DatatypeValidator* dv = curAttDef.getDatatypeValidator();
  386.          processDatatypeValidator( dv, true );
  387.         cout << "n";
  388.     }
  389. }
  390. void processDatatypeValidator( const DatatypeValidator* dtValidator, bool margin )
  391. {
  392.     if( !dtValidator )
  393.     {
  394.         return;
  395.     }
  396.     if( margin )
  397.     {
  398.         cout << "t";
  399.     }
  400.     cout << "Base Datatype:tt";
  401.     switch( dtValidator->getType() )
  402.     {
  403.     case DatatypeValidator::String:         cout << "string";      break;
  404.     case DatatypeValidator::AnyURI:         cout << "AnyURI";      break;
  405.     case DatatypeValidator::QName:          cout << "QName";       break;
  406. case DatatypeValidator::Name:           cout << "Name";        break;
  407. case DatatypeValidator::NCName:         cout << "NCName";      break;
  408.     case DatatypeValidator::Boolean:        cout << "Boolean";     break;
  409.     case DatatypeValidator::Float:          cout << "Float";       break;
  410.     case DatatypeValidator::Double:         cout << "Double";      break;
  411.     case DatatypeValidator::Decimal:        cout << "Decimal";     break;
  412.     case DatatypeValidator::HexBinary:      cout << "HexBinary";   break;
  413.     case DatatypeValidator::Base64Binary:   cout << "Base64Binary";break;
  414.     case DatatypeValidator::Duration:       cout << "Duration";    break;
  415.     case DatatypeValidator::DateTime:       cout << "DateTime";    break;
  416.     case DatatypeValidator::Date:           cout << "Date";        break;
  417.     case DatatypeValidator::Time:           cout << "Time";        break;
  418.     case DatatypeValidator::MonthDay:       cout << "MonthDay";    break;
  419.     case DatatypeValidator::YearMonth:      cout << "YearMonth";   break;
  420.     case DatatypeValidator::Year:           cout << "Year";        break;
  421.     case DatatypeValidator::Month:          cout << "Month";       break;
  422.     case DatatypeValidator::Day:            cout << "Day";         break;
  423.     case DatatypeValidator::ID:             cout << "ID";          break;
  424.     case DatatypeValidator::IDREF:          cout << "IDREF";       break;
  425.     case DatatypeValidator::ENTITY:         cout << "ENTITY";      break;
  426.     case DatatypeValidator::NOTATION:       cout << "NOTATION";    break;
  427.     case DatatypeValidator::List:           cout << "List";        break;
  428.     case DatatypeValidator::Union:          cout << "Union";       break;
  429.     case DatatypeValidator::AnySimpleType:  cout << "AnySimpleType"; break;
  430.     }
  431.     cout << "n";
  432.     // Facets
  433. RefHashTableOf<KVStringPair>* facets = dtValidator->getFacets();
  434.     if( facets )
  435.     {
  436.         RefHashTableOfEnumerator<KVStringPair> enumFacets(facets);
  437.         if( enumFacets.hasMoreElements() )
  438.         {
  439.             cout << "Facets:ttn";
  440.         }
  441.         while(enumFacets.hasMoreElements())
  442.         {
  443.             // Element's properties
  444.             const KVStringPair& curPair = enumFacets.nextElement();
  445.             cout << "t" << StrX( curPair.getKey() )    << "="
  446.                          << StrX( curPair.getValue() )  << "n";
  447.         }
  448.     }
  449. // Enumerations
  450. RefVectorOf<XMLCh>* enums = (RefVectorOf<XMLCh>*) dtValidator->getEnumString();
  451. if (enums)
  452. {
  453. cout << "Enumeration:ttn";
  454.         int enumLength = enums->size();
  455.         for ( int i = 0; i < enumLength; i++)
  456.         {
  457.             cout << "t" << StrX( enums->elementAt(i)) << "n";
  458.         }
  459. }
  460. }
  461. void processContentSpecNode( const ContentSpecNode* cSpecNode, bool margin )
  462. {
  463.     if( !cSpecNode )
  464.     {
  465.         return;
  466.     }
  467.     if( margin )
  468.     {
  469.         cout << "t";
  470.     }
  471.     cout << "ContentType:t";
  472.     switch( cSpecNode->getType() )
  473.     {
  474.         case ContentSpecNode::Leaf:             cout << "Leaf";           break;
  475.         case ContentSpecNode::ZeroOrOne:        cout << "ZeroOrOne";      break;
  476.         case ContentSpecNode::ZeroOrMore:       cout << "ZeroOrMore";     break;
  477.         case ContentSpecNode::OneOrMore:        cout << "OneOrMore";      break;
  478.         case ContentSpecNode::Choice:           cout << "Choice";         break;
  479.         case ContentSpecNode::Sequence:         cout << "Sequence";       break;
  480. case ContentSpecNode::All:              cout << "All";            break;
  481.         case ContentSpecNode::Any:              cout << "Any";            break;
  482.         case ContentSpecNode::Any_Other:        cout << "Any_Other";      break;
  483.         case ContentSpecNode::Any_NS:           cout << "Any_NS";         break;
  484.         case ContentSpecNode::Any_Lax:          cout << "Any_Lax";        break;
  485.         case ContentSpecNode::Any_Other_Lax:    cout << "Any_Other_Lax";  break;
  486.         case ContentSpecNode::Any_NS_Lax:       cout << "Any_NS_Lax";     break;
  487.         case ContentSpecNode::Any_Skip:         cout << "Any_Skip";       break;
  488.         case ContentSpecNode::Any_Other_Skip:   cout << "Any_Other_Skip"; break;
  489.         case ContentSpecNode::Any_NS_Skip:      cout << "Any_NS_Skip";    break;
  490.         case ContentSpecNode::UnknownType:      cout << "UnknownType";    break;
  491.     }
  492.     cout << "n";
  493. }