SEnumVal.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:19k
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 2001, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Id: SEnumVal.cpp,v 1.15 2003/02/05 18:53:24 tng Exp $
- * $Log: SEnumVal.cpp,v $
- * Revision 1.15 2003/02/05 18:53:24 tng
- * [Bug 11915] Utility for freeing memory.
- *
- * Revision 1.14 2003/01/14 15:32:45 knoaman
- * [Bug 16024] SchemaSymbols.hpp conflicts C++ Builder 6 dir.h
- *
- * Revision 1.13 2002/11/05 21:46:20 tng
- * Explicit code using namespace in application.
- *
- * Revision 1.12 2002/07/12 15:51:52 knoaman
- * Retrieve the root grammar instead of using the validator.
- * Modify the way we print substitution group info.
- *
- * Revision 1.11 2002/06/25 15:30:46 peiyongz
- * Bug#10067: SEnumVal bugs found when porting to Visual Studio .NET
- * projects, patch from Robert Buck (rbuck@mathworks.com )
- *
- * Revision 1.10 2002/05/08 18:18:46 knoaman
- * Fix bor bug 8301: INFINITY used as enum member.
- *
- * Revision 1.9 2002/04/17 20:18:08 tng
- * [Bug 7493] The word "occured" is misspelled and it is a global error.
- *
- * Revision 1.8 2002/02/20 20:30:11 peiyongz
- * Make the code compilable on Solaris 2.6's CC
- *
- * Revision 1.7 2002/02/14 15:14:58 peiyongz
- * getEnumString()
- *
- * Revision 1.6 2002/02/01 22:41:28 peiyongz
- * sane_include
- *
- * Revision 1.5 2001/11/22 14:47:48 tng
- * Use the phrase "Grammar" instead of "Validator" in EnumVal and SEnumVal Description.
- *
- * Revision 1.4 2001/11/21 22:09:49 peiyongz
- * Copy Right date
- *
- * Revision 1.3 2001/11/21 19:05:23 peiyongz
- * SEnumVal: GrammarType checked
- *
- *
- */
- // ---------------------------------------------------------------------------
- // Includes
- // ---------------------------------------------------------------------------
- #include <xercesc/util/NameIdPool.hpp>
- #include <xercesc/util/PlatformUtils.hpp>
- #include <xercesc/framework/XMLValidator.hpp>
- #include <xercesc/parsers/SAXParser.hpp>
- #include <xercesc/validators/schema/SchemaValidator.hpp>
- #include <xercesc/validators/common/ContentSpecNode.hpp>
- #include <xercesc/validators/schema/SchemaSymbols.hpp>
- #include <iostream.h>
- #include <stdlib.h>
- #include <string.h>
- XERCES_CPP_NAMESPACE_USE
- // ---------------------------------------------------------------------------
- // Forward references
- // ---------------------------------------------------------------------------
- static void usage();
- void process(char* const);
- void processAttributes( XMLAttDefList& attList, bool margin = false );
- void processDatatypeValidator( const DatatypeValidator*, bool margin = false
- );
- void processContentSpecNode( const ContentSpecNode* specNode, bool margin =
- false );
- // ---------------------------------------------------------------------------
- // This is a simple class that lets us do easy (though not terribly efficient)
- // trancoding of XMLCh data to local code page for display.
- // ---------------------------------------------------------------------------
- class StrX
- {
- public :
- // -----------------------------------------------------------------------
- // Constructors and Destructor
- // -----------------------------------------------------------------------
- StrX(const XMLCh* const toTranscode)
- {
- // Call the private transcoding method
- fLocalForm = XMLString::transcode(toTranscode);
- }
- ~StrX()
- {
- XMLString::release(&fLocalForm);
- }
- // -----------------------------------------------------------------------
- // Getter methods
- // -----------------------------------------------------------------------
- const char* localForm() const
- {
- return fLocalForm;
- }
- private :
- // -----------------------------------------------------------------------
- // Private data members
- //
- // fLocalForm
- // This is the local code page form of the string.
- // -----------------------------------------------------------------------
- char* fLocalForm;
- };
- inline ostream& operator<<(ostream& target, const StrX& toDump)
- {
- target << toDump.localForm();
- return target;
- }
- // ---------------------------------------------------------------------------
- // Local helper methods
- // ---------------------------------------------------------------------------
- static void usage()
- {
- cout << "nUsage:n"
- " SEnumVal <XML file>nn"
- "This program parses a file, then shows how to enumerate then"
- "contents of the Schema Grammar. Essentially, shows how one cann"
- "access the Schema information stored in internal data structures.n"
- << endl;
- }
- // ---------------------------------------------------------------------------
- // Program entry point
- // ---------------------------------------------------------------------------
- int main(int argC, char* argV[])
- {
- // Initialize the XML4C system
- try
- {
- XMLPlatformUtils::Initialize();
- }
- catch (const XMLException& toCatch)
- {
- cerr << "Error during initialization! Message:n"
- << StrX(toCatch.getMessage()) << endl;
- XMLPlatformUtils::Terminate();
- return 1;
- }
- // Check command line and extract arguments.
- // We only have one required parameter, which is the file to process
- if ((argC != 2) ||
- (*(argV[1]) == '-'))
- {
- usage();
- XMLPlatformUtils::Terminate();
- return 2;
- }
- try
- {
- process(argV[1]);
- }
- catch (const XMLException& e)
- {
- cerr << "nError during parsing: '" << argV[1] << "'n"
- << "Exception message is: n"
- << StrX(e.getMessage()) << "n" << endl;
- XMLPlatformUtils::Terminate();
- return 3;
- }
- XMLPlatformUtils::Terminate();
- return 0;
- }
- void process(char* const xmlFile)
- {
- //
- // Create a Schema validator to be used for our validation work. Then create
- // a SAX parser object and pass it our validator. Then, according to what
- // we were told on the command line, set it to validate or not. He owns
- // the validator, so we have to allocate it.
- //
- SAXParser parser;
- parser.setValidationScheme(SAXParser::Val_Always);
- parser.setDoNamespaces(true);
- parser.setDoSchema(true);
- parser.parse(xmlFile);
- if (parser.getErrorCount())
- {
- cout << "nErrors occurred, no output availablen" << endl;
- return;
- }
- if (!parser.getValidator().handlesSchema())
- {
- cout << "n Non schema document, no output availablen" << endl;
- return;
- }
- Grammar* rootGrammar = parser.getRootGrammar();
- if (!rootGrammar || rootGrammar->getGrammarType() != Grammar::SchemaGrammarType)
- {
- cout << "n Non schema grammar, no output availablen" << endl;
- return;
- }
- //
- // Now we will get an enumerator for the element pool from the validator
- // and enumerate the elements, printing them as we go. For each element
- // we get an enumerator for its attributes and print them also.
- //
- SchemaGrammar* grammar = (SchemaGrammar*) rootGrammar;
- RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
- if (!elemEnum.hasMoreElements())
- {
- cout << "nThe validator has no elements to displayn" << endl;
- return;
- }
- while(elemEnum.hasMoreElements())
- {
- const SchemaElementDecl& curElem = elemEnum.nextElement();
- // Name
- cout << "Name:ttt" << StrX(curElem.getFullName()) << "n";
- // Model Type
- cout << "Model Type:tt";
- switch( curElem.getModelType() )
- {
- case SchemaElementDecl::Empty: cout << "Empty"; break;
- case SchemaElementDecl::Any: cout << "Any"; break;
- case SchemaElementDecl::Mixed_Simple: cout << "Mixed_Simple"; break;
- case SchemaElementDecl::Mixed_Complex: cout << "Mixed_Complex"; break;
- case SchemaElementDecl::Children: cout << "Children"; break;
- case SchemaElementDecl::Simple: cout << "Simple"; break;
- default: cout << "Unknown"; break;
- }
- cout << "n";
- // Create Reason
- cout << "Create Reason:t";
- switch( curElem.getCreateReason() )
- {
- case XMLElementDecl::NoReason: cout << "Empty"; break;
- case XMLElementDecl::Declared: cout << "Declared"; break;
- case XMLElementDecl::AttList: cout << "AttList"; break;
- case XMLElementDecl::InContentModel: cout << "InContentModel"; break;
- case XMLElementDecl::AsRootElem: cout << "AsRootElem"; break;
- case XMLElementDecl::JustFaultIn: cout << "JustFaultIn"; break;
- default: cout << "Unknown"; break;
- }
- cout << "n";
- // Content Spec Node
- processContentSpecNode( curElem.getContentSpec() );
- // Misc Flags
- int mflags = curElem.getMiscFlags();
- if( mflags !=0 )
- {
- cout << "Misc. Flags:t";
- }
- if ( mflags & SchemaSymbols::XSD_NILLABLE )
- cout << "Nillable ";
- if ( mflags & SchemaSymbols::XSD_ABSTRACT )
- cout << "Abstract ";
- if ( mflags & SchemaSymbols::XSD_FIXED )
- cout << "Fixed ";
- if( mflags !=0 )
- {
- cout << "n";
- }
- // Substitution Name
- SchemaElementDecl* subsGroup = curElem.getSubstitutionGroupElem();
- if( subsGroup )
- {
- const XMLCh* uriText = parser.getURIText(subsGroup->getURI());
- cout << "Substitution Name:t" << StrX(uriText)
- << "," << StrX(subsGroup->getBaseName()) << "n";
- }
- // Content Model
- const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
- if( fmtCntModel != NULL )
- {
- cout << "Content Model:t" << StrX(fmtCntModel) << "n";
- }
- const ComplexTypeInfo* ctype = curElem.getComplexTypeInfo();
- if( ctype != NULL)
- {
- cout << "ComplexType:n";
- cout << "tTypeName:t" << StrX(ctype->getTypeName()) << "n";
- ContentSpecNode* cSpecNode = ctype->getContentSpec();
- processContentSpecNode(cSpecNode, true );
- }
- // Datatype
- DatatypeValidator* dtValidator = curElem.getDatatypeValidator();
- processDatatypeValidator( dtValidator );
- // Get an enumerator for this guy's attributes if any
- if ( curElem.hasAttDefs() )
- {
- processAttributes( curElem.getAttDefList() );
- }
- cout << "--------------------------------------------";
- cout << endl;
- }
- return;
- }
- //---------------------------------------------------------------------
- // Prints the Attribute's properties
- //---------------------------------------------------------------------
- void processAttributes( XMLAttDefList& attList, bool margin )
- {
- if ( attList.isEmpty() )
- {
- return;
- }
- if ( margin )
- {
- cout << "t";
- }
- cout << "Attributes:n";
- while( attList.hasMoreElements() )
- {
- // Name
- SchemaAttDef& curAttDef = (SchemaAttDef&)attList.nextElement();
- cout << "tName:ttt" << StrX(curAttDef.getFullName()) << "n";
- // Type
- cout << "tType:ttt";
- cout << StrX(XMLAttDef::getAttTypeString(curAttDef.getType()));
- cout << "n";
- // Default Type
- cout << "tDefault Type:t";
- cout << StrX(XMLAttDef::getDefAttTypeString(curAttDef.getDefaultType()));
- cout << "n";
- // Value
- if( curAttDef.getValue() )
- {
- cout << "tValue:ttt";
- cout << StrX(curAttDef.getValue());
- cout << "n";
- }
- // Enum. values
- if( curAttDef.getEnumeration() )
- {
- cout << "tEnumeration:t";
- cout << StrX(curAttDef.getEnumeration());
- cout << "n";
- }
- const DatatypeValidator* dv = curAttDef.getDatatypeValidator();
- processDatatypeValidator( dv, true );
- cout << "n";
- }
- }
- void processDatatypeValidator( const DatatypeValidator* dtValidator, bool margin )
- {
- if( !dtValidator )
- {
- return;
- }
- if( margin )
- {
- cout << "t";
- }
- cout << "Base Datatype:tt";
- switch( dtValidator->getType() )
- {
- case DatatypeValidator::String: cout << "string"; break;
- case DatatypeValidator::AnyURI: cout << "AnyURI"; break;
- case DatatypeValidator::QName: cout << "QName"; break;
- case DatatypeValidator::Name: cout << "Name"; break;
- case DatatypeValidator::NCName: cout << "NCName"; break;
- case DatatypeValidator::Boolean: cout << "Boolean"; break;
- case DatatypeValidator::Float: cout << "Float"; break;
- case DatatypeValidator::Double: cout << "Double"; break;
- case DatatypeValidator::Decimal: cout << "Decimal"; break;
- case DatatypeValidator::HexBinary: cout << "HexBinary"; break;
- case DatatypeValidator::Base64Binary: cout << "Base64Binary";break;
- case DatatypeValidator::Duration: cout << "Duration"; break;
- case DatatypeValidator::DateTime: cout << "DateTime"; break;
- case DatatypeValidator::Date: cout << "Date"; break;
- case DatatypeValidator::Time: cout << "Time"; break;
- case DatatypeValidator::MonthDay: cout << "MonthDay"; break;
- case DatatypeValidator::YearMonth: cout << "YearMonth"; break;
- case DatatypeValidator::Year: cout << "Year"; break;
- case DatatypeValidator::Month: cout << "Month"; break;
- case DatatypeValidator::Day: cout << "Day"; break;
- case DatatypeValidator::ID: cout << "ID"; break;
- case DatatypeValidator::IDREF: cout << "IDREF"; break;
- case DatatypeValidator::ENTITY: cout << "ENTITY"; break;
- case DatatypeValidator::NOTATION: cout << "NOTATION"; break;
- case DatatypeValidator::List: cout << "List"; break;
- case DatatypeValidator::Union: cout << "Union"; break;
- case DatatypeValidator::AnySimpleType: cout << "AnySimpleType"; break;
- }
- cout << "n";
- // Facets
- RefHashTableOf<KVStringPair>* facets = dtValidator->getFacets();
- if( facets )
- {
- RefHashTableOfEnumerator<KVStringPair> enumFacets(facets);
- if( enumFacets.hasMoreElements() )
- {
- cout << "Facets:ttn";
- }
- while(enumFacets.hasMoreElements())
- {
- // Element's properties
- const KVStringPair& curPair = enumFacets.nextElement();
- cout << "t" << StrX( curPair.getKey() ) << "="
- << StrX( curPair.getValue() ) << "n";
- }
- }
- // Enumerations
- RefVectorOf<XMLCh>* enums = (RefVectorOf<XMLCh>*) dtValidator->getEnumString();
- if (enums)
- {
- cout << "Enumeration:ttn";
- int enumLength = enums->size();
- for ( int i = 0; i < enumLength; i++)
- {
- cout << "t" << StrX( enums->elementAt(i)) << "n";
- }
- }
- }
- void processContentSpecNode( const ContentSpecNode* cSpecNode, bool margin )
- {
- if( !cSpecNode )
- {
- return;
- }
- if( margin )
- {
- cout << "t";
- }
- cout << "ContentType:t";
- switch( cSpecNode->getType() )
- {
- case ContentSpecNode::Leaf: cout << "Leaf"; break;
- case ContentSpecNode::ZeroOrOne: cout << "ZeroOrOne"; break;
- case ContentSpecNode::ZeroOrMore: cout << "ZeroOrMore"; break;
- case ContentSpecNode::OneOrMore: cout << "OneOrMore"; break;
- case ContentSpecNode::Choice: cout << "Choice"; break;
- case ContentSpecNode::Sequence: cout << "Sequence"; break;
- case ContentSpecNode::All: cout << "All"; break;
- case ContentSpecNode::Any: cout << "Any"; break;
- case ContentSpecNode::Any_Other: cout << "Any_Other"; break;
- case ContentSpecNode::Any_NS: cout << "Any_NS"; break;
- case ContentSpecNode::Any_Lax: cout << "Any_Lax"; break;
- case ContentSpecNode::Any_Other_Lax: cout << "Any_Other_Lax"; break;
- case ContentSpecNode::Any_NS_Lax: cout << "Any_NS_Lax"; break;
- case ContentSpecNode::Any_Skip: cout << "Any_Skip"; break;
- case ContentSpecNode::Any_Other_Skip: cout << "Any_Other_Skip"; break;
- case ContentSpecNode::Any_NS_Skip: cout << "Any_NS_Skip"; break;
- case ContentSpecNode::UnknownType: cout << "UnknownType"; break;
- }
- cout << "n";
- }