void XMLUtil::verifyElementName(const XMLElement *elem, const string &expectedName) { if (elem == NULL) { throw XMLParseException("Cannot verify name of NULL element"); } if (elem->Name() != expectedName) { stringstream ss; ss << "Element name '" << elem->Name() << "' does not match expected name '" << expectedName << "'"; throw XMLParseException(ss.str()); } }
const XMLAttribute *XMLUtil::findAttribute(const XMLElement *elem, const string &attr, const bool mandatory) { if (elem == NULL) { throw XMLParseException("Cannot find attribute of NULL element"); } const XMLAttribute *attribute = elem->FindAttribute(attr.c_str()); if (mandatory && attribute == NULL) { stringstream ss; ss << "Could not find attribute with name '" << attr << "' in element with name '" << elem->Name() << "'"; throw XMLParseException(ss.str()); } return attribute; }
const XMLElement *XMLUtil::findNextSibling(const XMLElement *elem, const string &name, const bool mandatory) { if (elem == NULL) { throw XMLParseException("Cannot find sibling of NULL element"); } const XMLElement *sibling = elem->NextSiblingElement(name.c_str()); if (mandatory && sibling == NULL) { stringstream ss; ss << "Could not find sibling with name '" << name << "' of parent '" << elem->Name() << "'"; throw XMLParseException(ss.str()); } return sibling; }
const XMLElement *XMLUtil::findChildElement(const XMLElement *elem, const string &name, const bool mandatory) { if (elem == NULL) { throw XMLParseException("Cannot find child element in NULL"); } const XMLElement *child = elem->FirstChildElement(name.c_str()); if (mandatory && child == NULL) { stringstream ss; ss << "Could not find child element with name '" << name << "' of parent '" << elem->Name() << "'"; throw XMLParseException(ss.str()); } return child; }
static std::string parseXMLIdentifier(std::streambuf& buffer) { std::stringstream identifier; { char c=buffer.sgetc(); if((c<'A' || c>'Z') && (c<'a' || c>'z')) { throw XMLParseException(); } buffer.snextc(); identifier<<c; } for(;;) { char c=buffer.sgetc(); if((c<'0' || c>'9') && (c<'A' || c>'Z') && (c<'a' || c>'z')) { break; } buffer.snextc(); identifier<<c; } return identifier.str(); }
void XMLUtil::parseDocumentFromString(XMLDocument &doc, const string &xml) { XMLError err = doc.Parse(xml.c_str()); if (err != XMLError::XML_SUCCESS) { throw XMLParseException("Failed to parse invalid XML"); } }
const XMLElement *XMLUtil::findChildElement(const XMLDocument &doc, const string &name, const bool mandatory) { const XMLElement *elem = doc.FirstChildElement(name.c_str()); if (mandatory && elem == NULL) { stringstream ss; ss << "Could not find root element with name '" << name << "'"; throw XMLParseException(ss.str()); } return elem; }
static XMLNode_SPtr parseXMLNode(std::streambuf& buffer) { // 1. Read Symbol name parseXMLSkipSpace(buffer); std::string id=parseXMLIdentifier(buffer); std::cout<<"Parse Id:"<<id<<std::endl; std::list<XMLNode_SPtr> children; std::string text; parseXMLSkipSpace(buffer); for(;;) { char c=buffer.sgetc(); char c2=buffer.snextc(); if((c=='/') && (c2=='>')) { buffer.snextc(); goto completeNode; } if(c=='>') { goto parseText; } // TODO: Parse attribute } parseText: std::cout<<"Parse Text"<<std::endl; { std::stringstream textbuffer; parseXMLSkipSpace(buffer); for(;;) { char c=buffer.sgetc(); char c2=buffer.snextc(); if(c!='<') { textbuffer<<c; } else { if(c2=='/') { buffer.snextc(); break; } // TODO: There may be other cases. children.push_back(parseXMLNode(buffer)); } } text=textbuffer.str(); } { std::string::reverse_iterator trimpos=text.rbegin(); while((trimpos!=text.rend()) && (*trimpos==' ' || *trimpos=='\n' || *trimpos=='\r')) { trimpos++; } text.erase(trimpos.base(),text.end()); } std::cout<<"Parse end"<<std::endl; { std::string endidentifier=parseXMLIdentifier(buffer); if(endidentifier!=id) { throw XMLParseException(); } parseXMLSkipSpace(buffer); char c=buffer.sgetc(); if(c!='>') { throw XMLParseException(); } buffer.snextc(); } completeNode: std::cout<<"Complete"<<std::endl; // Complete...just build and return it. XMLNode_SPtr node(new XMLNode(id, children, text)); return node; }