134#define XMLPARSER_TFE( T , S ) \
135 TEUCHOS_TEST_FOR_EXCEPTION( T, std::runtime_error, "XML parse error at line " << _lineNo << ": " << S )
151 bool gotRoot =
false;
152 std::stack<long> tagLineStarts;
153 std::stack<string> tags;
157 std::string tag, cdata;
158 unsigned char c1, c2;
159 Teuchos::map<std::string,string> attrs;
172 if (
_is->readBytes(&c1,1) < 1) {
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==
'_') {
201 getSTag(c2, tag, attrs, emptytag);
203 handler->startElement(tag,attrs);
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" );
224 else if (c2 ==
'!') {
235 XMLPARSER_TFE(
true,
"element not well-formed or exploits unsupported feature" );
238 else if ( (curopen > 0) && (c1 ==
'&') ) {
239 std::string chars =
"";
241 handler->characters(chars);
243 else if ( (curopen > 0) ) {
244 std::string chars =
"";
246 handler->characters(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() );
255 return handler->getObject();
269 bool tagover =
false;
273 XMLPARSER_TFE(
_is->readBytes(&c,1) < 1 ,
"EOF before end element was terminated");
277 XMLPARSER_TFE(
_is->readBytes(&c,1) < 1 ,
"EOF before end element was terminated");
280 XMLPARSER_TFE(1,
"end element not well-formed: expected '>'");
300void XMLParser::getSTag(
unsigned char lookahead, std::string &tag, Teuchos::map<std::string,string> &attrs,
bool &emptytag)
328 XMLPARSER_TFE(
_is->readBytes(&c,1) < 1 ,
"EOF before start element was terminated");
341 bool hadspace =
false;
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");
359 attname.push_back(c);
361 else if (
isSpace(c) || c==
'=' ) {
365 XMLPARSER_TFE(1,
"attribute not well-formed: expected whitespace or '='");
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 ==
'&' ) {
422 XMLPARSER_TFE( attrs.find(attname) != attrs.end() ,
"cannot have two attributes with the same name");
423 attrs[attname] = attval;
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");
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");
538 XMLPARSER_TFE(1,
"reference not well-formed: expected name or '#'");
546 if (lookahead ==
'\n') ++
_lineNo;
547 if (
_is->readBytes(&lookahead,1) < 1) {
557 if ( (0x41 <= c && c <= 0x5A) || (0x61 <= c && c <= 0x7A) ||
558 (0xC0 <= c && c <= 0xD6) || (0xD8 <= c && c <= 0xF6) ||
568 if (
isLetter(c) || (
'0' <= c && c <=
'9') ||
569 c==
'.' || c==
'-' || c==
'_' || c==
':' || c==0xB7 )
578 if ( c==0x20 || c==0x9 || c==0xD || c==0xA )
587 if ( c==0x9 || c==0xA || c==0xD || 0x20 <= c) {
600 if (
_is->readBytes(&c,1) < 1) {
Defines a class for assembling an XMLObject from XML input.
#define XMLPARSER_TFE(T, S)
A class providing a simple XML parser. Methods can be overloaded to exploit external XML parsing libr...
Smart reference counting pointer class for automatic garbage collection.
TreeBuildingXMLHandler assembles a XMLObject from your XML input.
Representation of an XML data tree. XMLObject is a ref-counted handle to a XMLObjectImplem object,...
static bool isLetter(unsigned char c)
Determine whether c matches the Letter production according to the XML specification.
void getReference(std::string &refstr)
Consumes a Reference production according to the XML specification.
static bool isSpace(unsigned char c)
Determine whether c matches the Space production according to the XML specification.
int getSpace(unsigned char &lookahead)
Consumes a Space (block of whitepace) production according to the XML specification.
static bool isNameChar(unsigned char c)
Determine whether c matches the NameChar production according to the XML specification.
XMLObject parse()
Consume the XMLInputStream to build an XMLObject.
void ignoreXMLDeclaration()
Ignore the rest of an XML declaration tag.
void getSTag(unsigned char lookahead, std::string &tag, Teuchos::map< std::string, string > &attrs, bool &emptytag)
Consume a STag production according to the XML specification. getSTag throws an std::exception if the...
RCP< XMLInputStream > _is
int assertChar(unsigned char cexp)
Determines if the next character on the stream.
void getETag(std::string &tag)
Consume a ETag production according to the XML specification. getETag throws an std::exception if the...
static bool isChar(unsigned char c)
Determine whether c matches the Char production according to the XML specification.
void getComment(long startLine)
Consume a Comment production according to the XML specification. getComment throws an std::exception ...
Teuchos::map< std::string, string > _entities
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.