📄 xmlparser.cc
字号:
// ******************************************************************************XMLEntityStream* UnparsedXMLEntityStream::getXMLEntityStream( const XMLString& getName, const XMLEntityStreamType& ofEntityType) { throw XMLParserException(&myXMLParser->XMLEntityStreamStack,"UnparsedXMLEntityStream::getXMLEntityStream() called!", XMLParserException::INTERNAL_ERR);};// ******************************************************************************void UnparsedXMLEntityStream::makeTextString() { throw XMLParserException(&myXMLParser->XMLEntityStreamStack,"UnparsedXMLEntityStream::makeTextString() called!", XMLParserException::INTERNAL_ERR);};// ******************************************************************************// ******************************************************************************// XMLParser// ******************************************************************************// ******************************************************************************// ******************************************************************************XMLParser::XMLParser() { if(DEBUGXMLPARSER) { printf("XMLParser::XMLParser()\n"); } myxmdsBytePoint=0;};// ******************************************************************************XMLParser::~XMLParser() { if(DEBUGXMLPARSER) { printf("XMLParser::~XMLParser()\n"); } if(rootXMLEntityStream != 0) { delete rootXMLEntityStream; } if(DEBUGXMLPARSER) { printf(" ...XMLParser deleted\n"); }};// ******************************************************************************Document* XMLParser::parseFromFile( const char* fileName) { if(DEBUGXMLPARSER) { printf("XMLParser::parseFromFile\n"); } XMLEntityStreamStack.clear(); rootXMLEntityStream = new RootXMLEntityStream(this,fileName); XMLEntityStreamStack.push_front(rootXMLEntityStream); // add default expansions for the general entities // < > & ' and " rootXMLEntityStream->addGeneralXMLEntityStream("lt","&#60;"); rootXMLEntityStream->addGeneralXMLEntityStream("gt","&#62;"); rootXMLEntityStream->addGeneralXMLEntityStream("amp","&#38;"); rootXMLEntityStream->addGeneralXMLEntityStream("apos","&#39;"); rootXMLEntityStream->addGeneralXMLEntityStream("quot","&#34;"); (*XMLEntityStreamStack.begin())=rootXMLEntityStream; theDocumentType=0; theDocument=0; rootVersionNum="1.0"; rootEncName=""; StandAlone=0; try { matchProduction01Document(); } catch (XMLException XMLErr) { printf("Could not load Document\n"); printf("due to the following XMLException:\n"); printf("%s",XMLErr.getError()); } catch (DOMException DOMErr) { printf("Could not load Document\n"); printf("due to the following DOMException:\n"); printf("%s",DOMErr.getError()); } if(DEBUGXMLPARSER) { myDOMImplementation.printAll(); } return(theDocument);};// ******************************************************************************unsigned long XMLParser::xmdsBytePoint() const { if(DEBUGXMLPARSER) { printf("XMLParser::xmdsBytePoint\n"); } return myxmdsBytePoint;}/* The folowwing routines are designed to parse the productions laid out in XML 1.0 (second edition). These productions fall into three categories: 1. Required. An error at any stage of parsing a required production will generate the XMLParserException BAD_XML_ERR. These routines are declared with the return type void. 2. Optional. An error at the early stages of parsing will not be reported and the routine will back out and return 0. If the parsing passes a 'critical point' (the point at which the intended production is uniquely specified) the routine will generate the XMLParserException BAD_XML_ERR so that the user may know where they are going wrong. These routines are declared as type bool so that the calling routine knows whether or not the attempted parse was successful. 3. Either of the above, in which case the routine is passed a bool parameter 'required' so that it knows which behaviour is expected. The definition of where the 'critical point' should go is not easy, as many productons are comprised of ORed subproductions, and yet it would be nice to be able to feed reasonable error messages to the user if they have made a reconisable attempt at a particular production. Therefore many productions test for their subproductions in a particular order, with the last one to be tested having a very early critical point, and yeilding error messages that encompass all the other subproductions.*/// ******************************************************************************void XMLParser::matchProduction01Document() { // this production is required if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction01Document\n"); } matchProduction22Prolog(); if(!matchProduction39Element(0)) { // no root element throw XMLParserException(&XMLEntityStreamStack, "Root element expected.",XMLParserException::BAD_XML_ERR); } while(matchProduction27Misc(0)); // what is this supposed to do?? PTC //char c = (*XMLEntityStreamStack.begin())->nextChar(); signed char c = (*XMLEntityStreamStack.begin())->nextChar(); if(c!=EOF) { // what is this extra stuff? throw XMLParserException(&XMLEntityStreamStack, "End of file expected.",XMLParserException::BAD_XML_ERR); }};// ******************************************************************************long XMLParser::matchProduction03S( XMLEntityStream *const thisStream, const bool required) const { // this production is sometimes required and sometimes optional if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction03S\n"); } StreamPositionStruct lastStreamPos = thisStream->streamPos; long length=0; //char c=thisStream->nextChar(); signed char c=thisStream->nextChar(); while(XMLChar::isWhiteSpace(c)&(c!=EOF)) { lastStreamPos = thisStream->streamPos; length++; c=thisStream->nextChar(); } if(!XMLChar::isWhiteSpace(c)) { thisStream->streamPos = lastStreamPos; } if((length==0)&required) { throw XMLParserException(&XMLEntityStreamStack, "White space expected.",XMLParserException::BAD_XML_ERR); } return length;};// ******************************************************************************long XMLParser::matchProduction03SDeep( const bool required) { // this production is like the normal whitespace production, // except that it also descends and climbs PE streams, since // allowable white space forms logical boundaries between atoms of a DTD if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction03SDeep\n"); } if(XMLEntityStreamStack.size()==1) { return matchProduction03S((*XMLEntityStreamStack.begin()),required); } StreamPositionStruct lastStreamPos = (*XMLEntityStreamStack.begin())->streamPos; XMLEntityStream* nextXMLEntityStream; long length=0; //char c=(*XMLEntityStreamStack.begin())->nextChar(); signed char c=(*XMLEntityStreamStack.begin())->nextChar(); while(XMLChar::isWhiteSpace(c)|(c=='%')|(c==EOF)) { if(c==EOF) { if(XMLEntityStreamStack.size()==1) { throw XMLParserException(&XMLEntityStreamStack,"Unexpected end of file", XMLParserException::BAD_XML_ERR); } XMLEntityStreamStack.pop_front(); } else if(c=='%') { // might yet be the % in an <!ENTITY % name ...> declaration // therefore check next character, and proceed only if not a WhiteSpace c=(*XMLEntityStreamStack.begin())->nextChar(); if(!XMLChar::isWhiteSpace(c)) { (*XMLEntityStreamStack.begin())->streamPos.count -= 2; (*XMLEntityStreamStack.begin())->streamPos.columnNumber -= 2; XMLString refName; StreamPositionStruct lastStreamPos2 = (*XMLEntityStreamStack.begin())->streamPos; matchProduction69PEReference((*XMLEntityStreamStack.begin()),refName); nextXMLEntityStream = (*XMLEntityStreamStack.begin())->getXMLEntityStream(refName,XMLEntityStream::PARAMETER_ENTITY); if(nextXMLEntityStream==0) { (*XMLEntityStreamStack.begin())->streamPos = lastStreamPos2; sprintf(errormessage,"Parameter entity '%s' unknown",refName.c_str()); throw XMLParserException(&XMLEntityStreamStack,errormessage,XMLParserException::BAD_XML_ERR); } XMLEntityStreamStack.push_front(nextXMLEntityStream); } else { (*XMLEntityStreamStack.begin())->streamPos = lastStreamPos; if((length==0)&required) { throw XMLParserException(&XMLEntityStreamStack,"White space expected",XMLParserException::BAD_XML_ERR); } return length; } } length++; lastStreamPos = (*XMLEntityStreamStack.begin())->streamPos; c=(*XMLEntityStreamStack.begin())->nextChar(); } (*XMLEntityStreamStack.begin())->streamPos = lastStreamPos; if((length==0)&required) { throw XMLParserException(&XMLEntityStreamStack,"White space expected",XMLParserException::BAD_XML_ERR); } return length;};// ******************************************************************************bool XMLParser::matchProduction05Name( XMLEntityStream *const thisStream, XMLString& Name) const { // this production is optional if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction05Name\n"); } if(!matchProduction07Nmtoken(thisStream,Name)) { return 0; } // critical point // and check that it is a valid name if(!Name.isName()) { thisStream->streamPos.columnNumber -= Name.length(); throw XMLParserException(&XMLEntityStreamStack,"Not a valid Name",XMLParserException::BAD_XML_ERR); } if(DEBUGXMLPARSER) { printf("Name = '%s'\n",Name.c_str()); } return 1;};// ******************************************************************************bool XMLParser::matchProduction07Nmtoken( XMLEntityStream *const thisStream, XMLString& Nmtoken) const { // this production is optional if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction07Nmtoken\n"); } StreamPositionStruct lastStreamPos = thisStream->streamPos; // first of all need to determine length of NMToken unsigned long length=0; //char c=thisStream->nextChar(); signed char c=thisStream->nextChar(); if(c==EOF) { return 0; } while(XMLChar::isNameChar(c)) { length++; c=thisStream->nextChar(); } thisStream->streamPos = lastStreamPos; if(length==0) { return 0; } char* s = new char[length+1]; for(unsigned long i=0; i<length; i++) { s[i]=thisStream->nextChar(); } s[length]=0; Nmtoken=s; delete s; if(DEBUGXMLPARSER) { printf("Nmtoken = '%s'\n",Nmtoken.c_str()); } return 1;};// ******************************************************************************void XMLParser::matchProduction09EntityLiteral( XMLString& EntityLiteral) { // this production is required if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction09EntityLiteral\n"); } matchProductionQuotedString((*XMLEntityStreamStack.begin()),EntityLiteral);};// ******************************************************************************void XMLParser::matchProduction10AttValue( XMLString& AttValue) { // this production is required if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction_AttVal\n"); } matchProductionQuotedString((*XMLEntityStreamStack.begin()),AttValue); // check it for "<" for(unsigned long i=0;i<AttValue.length();i++) { if(AttValue.data(i)=='<') { // illegal '<' throw XMLParserException(&XMLEntityStreamStack,"'<' not allowed in AttValue",XMLParserException::BAD_XML_ERR); } } // now scan it for references and replace if known *MOREWORK};// ******************************************************************************void XMLParser::matchProduction11SystemLiteral( XMLString& SystemLiteral) { // this production is required if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction11SystemLiteral\n"); } matchProductionQuotedString((*XMLEntityStreamStack.begin()),SystemLiteral);};// ******************************************************************************void XMLParser::matchProduction12PubidLiteral( XMLString& PubidLiteral) { // this production is required if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction12PubidLiteral\n"); } matchProductionQuotedString((*XMLEntityStreamStack.begin()),PubidLiteral); if(!PubidLiteral.isPubidLiteral()) { (*XMLEntityStreamStack.begin())->streamPos.columnNumber -= PubidLiteral.length() + 1; throw XMLParserException(&XMLEntityStreamStack,"not a valid PubidLiteral",XMLParserException::BAD_XML_ERR); }};// ******************************************************************************bool XMLParser::matchProduction14CharData( Element* containingElement) { // this production is optional if(DEBUGXMLPARSER) { printf("XMLParser::matchProduction14CharData\n"); } list<XMLEntityStream*> lastXMLEntityStreamStack; list<StreamPositionStruct> lastStreamsPosition;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -