xmlparser.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 982 行 · 第 1/2 页

CPP
982
字号
//XMLParser.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*///XMLParser.h#include "vcf/FoundationKit/FoundationKit.h"using namespace VCF;String XMLAttr::toString(){	String result = " " + getName() + "=\"" + getValue() + "\" ";	return result;}XMLNode::XMLNode( const String& name, XMLNode* parentNode ){	name_ = name;	parentNode_ = parentNode;	attrsContainer_.initContainer( attrs_ );	childNodesContainer_.initContainer( childNodes_ );	if ( NULL != parentNode ) {		parentNode->addChildNode( this );	}}XMLNode::XMLNode( const XMLNode& node ) :    Object(node){	name_ = node.name_;	parentNode_ = node.parentNode_;	CDATA_ = node.CDATA_;	attrs_ = node.attrs_;	//childNodes_ = node.childNodes_;	std::vector<XMLNode*>::const_iterator it = node.childNodes_.begin();	while ( it != node.childNodes_.end() ) {		XMLNode* childNode = *it;		XMLNode* newNode = new XMLNode( *childNode );		addChildNode( newNode );		it ++;	}	attrsContainer_.initContainer( attrs_ );	childNodesContainer_.initContainer( childNodes_ );}XMLNode::~XMLNode(){	clearChildNodes();}XMLNode& XMLNode::operator = ( const XMLNode& node ){	clearChildNodes();	name_ = node.name_;	parentNode_ = node.parentNode_;	CDATA_ = node.CDATA_;	attrs_ = node.attrs_;	std::vector<XMLNode*>::const_iterator it = node.childNodes_.begin();	while ( it != node.childNodes_.end() ) {		XMLNode* childNode = *it;		XMLNode* newNode = new XMLNode( *childNode );		addChildNode( newNode );		it ++;	}	attrsContainer_.initContainer( attrs_ );	childNodesContainer_.initContainer( childNodes_ );	return *this;}XMLAttr* XMLNode::getAttrByName( const String& name ){	XMLAttr* result = NULL;	std::vector<XMLAttr>::iterator it = attrs_.begin();	while ( it != attrs_.end() ){		if ( name == (*it).getName() ) {			result = &(*it);			break;		}		it ++;	}	return result;}XMLAttr* XMLNode::getAttrByIndex( const ulong32& index ){	XMLAttr* result = NULL;	if ( index < attrs_.size() ) {		result = &attrs_[index];	}	return result;}void XMLNode::removeNode( XMLNode* node ){	std::vector<XMLNode*>::iterator found = std::find( childNodes_.begin(), childNodes_.end(), node );	if ( found != childNodes_.end() ){		childNodes_.erase( found );	}}XMLNode* XMLNode::getNodeByName( const String& name ){	XMLNode* result = NULL;	std::vector<XMLNode*>::iterator it = childNodes_.begin();	while ( it != childNodes_.end() ) {		XMLNode* node = *it;		if ( node->getName() == name ) {			result = node;			break;		}		it ++;	}	return result;}XMLNode* XMLNode::getNodeByIndex( const ulong32& index ){	XMLNode* result = NULL;	if ( (index >= 0) && (index < childNodes_.size()) ) {		result = childNodes_[index];	}	return result;}void XMLNode::clearChildNodes(){	std::vector<XMLNode*>::iterator it = childNodes_.begin();	while ( it != childNodes_.end() ) {		XMLNode* node = *it;		delete node;		node = NULL;		it ++;	}	childNodes_.clear();}long XMLNode::getDepth(){	long result = 0;	XMLNode* parent = getParentNode();	while ( NULL != parent ) {		result ++;		parent = parent->getParentNode();	}	return result;}String XMLNode::toString(){	String result;	String tab;	int tabsize = getDepth();	for ( int i=0;i<tabsize;i++) {		tab += "\t";	}	String nodeString = tab + "<" + getName() + " ";	result += nodeString;	std::vector<XMLAttr>::iterator attrIt = attrs_.begin();	while ( attrIt != attrs_.end() ){		XMLAttr* attr = &(*attrIt);		result += attr->toString();		attrIt ++;	}	if ( true == childNodes_.empty() && true == CDATA_.empty() ) {		nodeString = "/>";		result += nodeString;	}	else {		nodeString = ">\n";		result += nodeString;		if ( !CDATA_.empty() ) {			result += tab + "\t" + CDATA_ + "\n";		}		std::vector<XMLNode*>::iterator nodeIt = childNodes_.begin();		while ( nodeIt != childNodes_.end() ) {			XMLNode* node = *nodeIt;			result += node->toString();			nodeIt ++;		}		nodeString = tab + "</" + getName() + ">";		result += nodeString;	}	// Only write out the ending newline if we're not the root node	if (tabsize>0) {		result += "\n";	}	return result;}XMLParser::XMLParser(){	parsedNodesContainer_.initContainer( parsedNodes_ );	currentNode_ = NULL;	dtdStarted_ = false;	entityMap_["amp"] = "&";	entityMap_["quot"] = "\"";	entityMap_["apos"] = "'";	entityMap_["lt"] = "<";	entityMap_["gt"] = ">";}XMLParser::~XMLParser(){	clearNodes();}Enumerator<XMLNode*>* XMLParser::getParsedNodes(){	return parsedNodesContainer_.getEnumerator();}void XMLParser::clearNodes(){	std::vector<XMLNode*>::iterator it = parsedNodes_.begin();	if ( it != parsedNodes_.end() ) {		// the first node is the root, delete it, and all the children go as well		XMLNode* node = *it;		delete node;		node = NULL;	}	parsedNodes_.clear();}void XMLParser::parse( const String& xmlString ){	currentNode_ = NULL;	clearNodes();	if ( ! xmlString.empty() ) {		sourcePtr_ = xmlString.c_str();		xmlBufferStart_ = sourcePtr_;		sourceSize_ = xmlString.size();		while ( nextNode() ) {		}	}}void XMLParser::parse( InputStream* stream ){	uint32 sz = stream->getSize();	if ( sz == 0 ) { //nothing to parse		return;	}	char* tmpBuffer = new char[sz+1];	memset( tmpBuffer, 0, (sz+1)*sizeof(char));	stream->seek( 0, stSeekFromStart );	stream->read( (unsigned char*)tmpBuffer, sz );		UnicodeString::AnsiChar* strBuf = tmpBuffer;	int bom = UnicodeString::adjustForBOMMarker( strBuf, sz );	String xmlText;	switch ( bom ) {		case UnicodeString::UTF8BOM : {			xmlText.assign( strBuf, sz );		}		break;		case UnicodeString::UTF16LittleEndianBOM : {			xmlText.assign( (UnicodeString::UniChar*)strBuf, sz / sizeof(UnicodeString::UniChar) );		}		break;		case UnicodeString::UTF32BigEndianBOM : //case UnicodeString::UTF16BigEndianBOM :		case UnicodeString::UTF32LittleEndianBOM :  {			//barf!!!			throw RuntimeException( MAKE_ERROR_MSG_2("Unable to handle this kind of Unicode BOM marked text!") );		}		break;		default : {			xmlText.assign( strBuf, sz );		}		break;	}	delete [] tmpBuffer;	parse( xmlText );}const VCFChar* XMLParser::skipWhitespace( const VCFChar* start, const int& length ){	const VCFChar* result = start;	while ( ((result-start) < length) && (*result == ' ') || (*result == '\n') || (*result == '\t') || (*result == '\r') ) {		result ++;	}	return result;}const VCFChar* XMLParser::skipTillWhitespace( const VCFChar* start, const int& length ){	const VCFChar* result = start;	while ( ((result-start) < length) && (*result != ' ') && (*result != '\n') && (*result != '\t') && (*result != '\r') ) {		result ++;	}	return result;}void XMLParser::parseEntity( const VCFChar* entityPtrStart, const VCFChar* entityPtrEnd ){}bool XMLParser::nextNode(){	if ( sourceSize_ <= (sourcePtr_ - xmlBufferStart_) ) {		return false;	}	const VCFChar* P = sourcePtr_;	const VCFChar* tokenStart;	while ( (*P != 0) && ((' ' == *P) || (13 == *P) || (10 == *P) || (9 == *P)) ) {		P++;	}	tokenPtr_ = P;	switch( *P ) {		case ']' : {			if ( dtdStarted_ ) {				while ( (*P != XMLParser::TagClose) && (*P != 0) ) {					P++;				}				P++;				sourcePtr_ = P;				dtdStarted_ = false;				return true;			}		}		break;		case XMLParser::TagOpen : {			P++;			tokenStart = P;			if ( *P == '?' ) {				P++;				//processing instructions - skip for now				while ( (*P != '?') && (*P != 0) ) {					P++;				}				if ( *P != '?' ) {					throw RuntimeException( "Malformed XML processing node - end '?' expected, but none found." );				}				P++;				P = skipWhitespace( P, sourceSize_-(P-sourcePtr_) );				if ( *P != XMLParser::TagClose ) {					throw RuntimeException( "Malformed XML processing node - end '>' expected, but none found." );				}				P++;				sourcePtr_ = P;				return true;			}			else if ( *P == '!' ) {				//check for '!'				P++;				if ( (*P == '-') && (*(P+1) == '-') ) {					P += 2;					//comment					const VCFChar* endComments = parseComments( P );					P = endComments;					P++;					sourcePtr_ = P;					return true;				}				String test;				test.append( P, 25 );				if ( test.find( "DOCTYPE" ) != String::npos ) {					while ( ((*P != XMLParser::TagClose) && (*P != '[')) && (*P != 0) ) {						P++;					}					if ( *P != XMLParser::TagClose ) {						dtdStarted_ = true;					}					else {						dtdStarted_ = false;					}					//skip over the doctype decl					P++;					sourcePtr_ = P;										return true;				}				else if ( test.find( "ENTITY" ) != String::npos ) {					P += 6;					tokenStart = P;					while ( (*P != XMLParser::TagClose) && (*P != 0) ) {						P++;					}					parseEntity( tokenStart, P );					P++;					sourcePtr_ = P;					return true;				}				else if ( test.find( "[CDATA[" ) != String::npos ) {					P += 7;					tokenPtr_ = P;					while ( ((*P != ']') || (*(P+1) != ']') ||							(*(P+2) != XMLParser::TagClose)) && (*P != 0) ) {						P++;					}					tokenString_ = "";					tokenString_.append( tokenPtr_, P - tokenPtr_ );					if ( NULL != currentNode_ ) {						currentNode_->setCDATA( currentNode_->getCDATA() + tokenString_ );							XMLParserEvent event( this, currentNode_ );							NodeCDATAFound.fireEvent( &event );					}					P+= 3;				}			}			else {				if ( *tokenStart != XMLParser::TagEnd ) {					//parse the node for attributes					XMLNode* node = new XMLNode("", currentNode_ );					parsedNodes_.push_back( node );					currentNode_ = node;					P = parseNode( tokenStart, P+(sourceSize_-(P-sourcePtr_)) );				}				else {					while ( (*P != XMLParser::TagClose) && (*P != 0) ) {						P++;					}				}				const VCFChar* endTag = P;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?