52 #include "Teuchos_Assert.hpp" 
   55 using namespace Teuchos;
 
  134 #define XMLPARSER_TFE( T , S ) \ 
  135   TEUCHOS_TEST_FOR_EXCEPTION( T, std::runtime_error, "XML parse error at line " << _lineNo << ": " << S ) 
  143   _entities[
"apos"] = 
"'";
 
  144   _entities[
"quot"] = 
"\"";
 
  145   _entities[
"lt"]   = 
"<";
 
  146   _entities[
"gt"]   = 
">";
 
  147   _entities[
"amp"]  = 
"&";
 
  151   bool gotRoot = 
false;
 
  152   std::stack<long> tagLineStarts;
 
  153   std::stack<string> tags;
 
  157     std::string tag, cdata;
 
  158     unsigned char c1, c2;
 
  165       if ( getSpace(c1) ) {
 
  172       if (_is->readBytes(&c1,1) < 1) {
 
  176       if (c1 == 
'\n') ++_lineNo; 
 
  182       XMLPARSER_TFE( _is->readBytes(&c2,1) < 1 , 
"stream ended in tag begin/end");
 
  189         XMLPARSER_TFE( curopen == 0,  
"document not well-formed: encountered end element '" << tag << 
"' while not enclosed." );
 
  190         XMLPARSER_TFE( handler->
endElement(tag)!=0, 
"document not well-formed: end element tag = '" << tag << 
"'" 
  191                                                     << 
" did not match start element '" << tags.top()
 
  192                                                     << 
"' from line " << tagLineStarts.top() );
 
  197       else if (isLetter(c2) || c2==
':' || c2==
'_') {
 
  200         tagLineStarts.push(_lineNo);
 
  201         getSTag(c2, tag, attrs, emptytag);
 
  205           XMLPARSER_TFE(gotRoot == 
true, 
"document not well-formed: more than one root element specified" );
 
  211           XMLPARSER_TFE( handler->
endElement(tag)!=0, 
"unknown failure from handler while processing tag '" << tag << 
"'" );
 
  217       else if (c2 == 
'?') {
 
  219         XMLPARSER_TFE( assertChar(
'x') != 0 , 
"was expecting an XML declaration; element not well-formed or exploits unsupported feature" );
 
  220         XMLPARSER_TFE( assertChar(
'm') != 0 , 
"was expecting an XML declaration; element not well-formed or exploits unsupported feature" );
 
  221         XMLPARSER_TFE( assertChar(
'l') != 0 , 
"was expecting an XML declaration; element not well-formed or exploits unsupported feature" );
 
  222         ignoreXMLDeclaration();
 
  224       else if (c2 == 
'!') {
 
  230         XMLPARSER_TFE( assertChar(
'-') != 0 , 
"element not well-formed or exploits unsupported feature" );
 
  231         XMLPARSER_TFE( assertChar(
'-') != 0 , 
"element not well-formed or exploits unsupported feature" );
 
  235         XMLPARSER_TFE(
true,  
"element not well-formed or exploits unsupported feature" );
 
  238     else if ( (curopen > 0) && (c1 == 
'&') ) {
 
  239       std::string chars = 
"";
 
  243     else if ( (curopen > 0) ) {
 
  244       std::string chars = 
"";
 
  249       XMLPARSER_TFE(1 , 
"document not well-formed: character data outside of an enclosing tag");
 
  253   XMLPARSER_TFE( curopen != 0 ,  
"file ended before closing element '" << tags.top() << 
"' from line " << tagLineStarts.top() );
 
  260 void XMLParser::getETag(std::string &tag)
 
  269   bool tagover = 
false;
 
  273   XMLPARSER_TFE( _is->readBytes(&c,1) < 1 ,  
"EOF before end element was terminated");
 
  274   XMLPARSER_TFE( !isLetter(c) && c!=
'_' && c!=
':' ,  
"tag not well-formed");
 
  277     XMLPARSER_TFE( _is->readBytes(&c,1) < 1 ,  
"EOF before end element was terminated");
 
  278     if ( isNameChar(c) ) {
 
  280         XMLPARSER_TFE(1,  
"end element not well-formed: expected '>'");
 
  284     else if (isSpace(c)) {
 
  287       if (c == 
'\n') ++_lineNo;
 
  294       XMLPARSER_TFE(1,  
"end element not well-formed");
 
  328     XMLPARSER_TFE( _is->readBytes(&c,1) < 1 ,  
"EOF before start element was terminated");
 
  341     bool hadspace = 
false;
 
  346       XMLPARSER_TFE( getSpace(c)!=0, 
"EOF before start element was terminated");
 
  350     if ( (isLetter(c) || c==
'_' || c==
':') && hadspace ) {
 
  354       std::string attname, attval;
 
  357         XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before start element was terminated");
 
  358         if ( isNameChar(c) ) {
 
  359           attname.push_back(c);
 
  361         else if ( isSpace(c) || c==
'=' ) {
 
  365           XMLPARSER_TFE(1,  
"attribute not well-formed: expected whitespace or '='");
 
  375         XMLPARSER_TFE(1,  
"attribute not well-formed: expected '='");
 
  379       XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before start element was terminated");
 
  390       else if (c == 
'\"') {
 
  394         XMLPARSER_TFE(1,  
"attribute value must be quoted with either ''' or '\"'");
 
  397         XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before start element was terminated");
 
  398         if (apost && c==
'\'') {
 
  402         else if (!apost && c==
'\"') {
 
  406         else if ( c == 
'&' ) {
 
  409           getReference(refstr);
 
  417           XMLPARSER_TFE(1,  
"invalid character in attribute value");
 
  422       XMLPARSER_TFE( attrs.find(attname) != attrs.end() ,  
"cannot have two attributes with the same name");
 
  423       attrs[attname] = attval;
 
  430       XMLPARSER_TFE(assertChar(
'>')!=0, 
"empty element tag not well-formed: expected '>'");
 
  435       XMLPARSER_TFE(1,  
"start element not well-formed: invalid character");
 
  439     XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before start element was terminated");
 
  445 void XMLParser::getComment(
long )
 
  456     XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before terminating comment begun at line " << _lineNo );
 
  457     if (c == 
'\n') ++_lineNo;
 
  461       XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before terminating comment begun at line " << _lineNo );
 
  462       if (c == 
'\n') ++_lineNo;
 
  465         XMLPARSER_TFE( assertChar(
'>')!=0, 
"comment not well-formed: missing expected '>' at line " << _lineNo );
 
  468       else if (!isChar(c)) {
 
  469         XMLPARSER_TFE(1,  
"comment not well-formed: invalid character at line " << _lineNo );
 
  472     else if (!isChar(c)) {
 
  473       XMLPARSER_TFE(1,  
"comment not well-formed: invalid character at line " << _lineNo );
 
  479 void XMLParser::getReference(std::string &refstr) {
 
  482   unsigned int num, base;
 
  485   XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before reference was terminated");
 
  491     XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before reference was terminated");
 
  496     else if (
'0' <= c && c <= 
'9') {
 
  501       XMLPARSER_TFE(1,  
"invalid character in character reference: expected 'x' or [0-9]");
 
  505       XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before reference was terminated");
 
  506       XMLPARSER_TFE( c != 
';' && !(
'0' <= c && c <= 
'9') ,  
"invalid character in character reference: expected [0-9] or ';'");
 
  510       num = num*base + (c-
'0');
 
  512     XMLPARSER_TFE(num > 0xFF,  
"character reference value out of range");
 
  513     refstr.push_back( (
unsigned char)num );
 
  515   else if (isLetter(c) || c==
'_' || c==
':') {
 
  518     std::string entname = 
"";
 
  519     entname.push_back(c);
 
  521       XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before reference was terminated");
 
  525       else if ( isLetter(c) || (
'0' <= c && c <= 
'9')
 
  526                 || c==
'.' || c==
'-' || c==
'_' || c==
':' 
  528         entname.push_back(c);
 
  531         XMLPARSER_TFE(1,  
"entity reference not well-formed: invalid character");
 
  534     XMLPARSER_TFE( _entities.find(entname) == _entities.end(),  
"entity reference not well-formed: undefined entity");
 
  535     refstr = _entities[entname];
 
  538     XMLPARSER_TFE(1,  
"reference not well-formed: expected name or '#'");
 
  543 int XMLParser::getSpace(
unsigned char &lookahead) {
 
  546     if (lookahead == 
'\n') ++_lineNo;
 
  547     if (_is->readBytes(&lookahead,1) < 1) {
 
  551   while (isSpace(lookahead));
 
  556 bool XMLParser::isLetter(
unsigned char c) {
 
  557   if ( (0x41 <= c && c <= 0x5A) || (0x61 <= c && c <= 0x7A) ||
 
  558        (0xC0 <= c && c <= 0xD6) || (0xD8 <= c && c <= 0xF6) ||
 
  567 bool XMLParser::isNameChar(
unsigned char c) {
 
  568   if ( isLetter(c) || (
'0' <= c && c <= 
'9') ||
 
  569        c==
'.' || c==
'-' || c==
'_' || c==
':' || c==0xB7 )
 
  577 bool XMLParser::isSpace(
unsigned char c) {
 
  578   if ( c==0x20 || c==0x9 || c==0xD || c==0xA )
 
  586 bool XMLParser::isChar(
unsigned char c) {
 
  587   if ( c==0x9 || c==0xA || c==0xD || 0x20 <= c) {  
 
  594 int XMLParser::assertChar(
unsigned char cexp)
 
  600   if (_is->readBytes(&c,1) < 1) {
 
  609 void XMLParser::ignoreXMLDeclaration()
 
  616     XMLPARSER_TFE(_is->readBytes(&c,1) < 1,  
"EOF before terminating XML declaration begun at line " << _lineNo );
 
  617     if (c == 
'\n') ++_lineNo;
 
  621       XMLPARSER_TFE( assertChar(
'>')!=0, 
"XML declaration not well-formed: missing expected '>' at line " << _lineNo );
 
void characters(const std::string &chars)
Process character data. 
 
Defines a class for assembling an XMLObject from XML input. 
 
int endElement(const std::string &tag)
Receive notification of the end of an element. 
 
XMLObject parse()
Consume the XMLInputStream to build an XMLObject. 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated. 
 
Representation of an XML data tree. XMLObject is a ref-counted handle to a XMLObjectImplem object...
 
void startElement(const std::string &tag, const Map &attributes)
Receive notification of the start of an element. 
 
const XMLObject & getObject() const 
Retrieve the entire XML tree. 
 
TreeBuildingXMLHandler assembles a XMLObject from your XML input. 
 
Smart reference counting pointer class for automatic garbage collection. 
 
A class providing a simple XML parser. Methods can be overloaded to exploit external XML parsing libr...