///Called from each XML class during its construction void XMLConversion::RegisterXMLFormat(XMLBaseFormat* pFormat, bool IsDefault, const char* uri) { if(IsDefault || Namespaces().empty()) _pDefault=pFormat; if(uri) Namespaces()[uri] = pFormat; else Namespaces()[pFormat->NamespaceURI()] = pFormat; }
bool XMLConversion::ReadXML(XMLBaseFormat* pFormat, OBBase* pOb) { if(_requestedpos) { //The initial stream position was not at the start, probably because of fastsearch //Read and discard the first object to synchronize the reader, //then continue getting the requested object. //Assumes the objects are all at the same level in the DOM tree. SetOneObjectOnly(); //probably already set streampos SavedReqestedPos = _requestedpos; _requestedpos=0;//don't do this again ReadXML(pFormat,pOb); GetInStream()->seekg(SavedReqestedPos); } //**Parse int result=1; while(GetInStream()->good() && (_SkipNextRead || (result=xmlTextReaderRead(_reader))==1)) //read may not be called { _SkipNextRead=false; if(_LookingForNamespace) { const xmlChar* puri = xmlTextReaderConstNamespaceUri(_reader); if(puri) { string uri((const char*)puri); //Look up appropriate format class from the namespace URI NsMapType::iterator nsiter; nsiter = Namespaces().find(uri); if(nsiter!=Namespaces().end()) { XMLBaseFormat* pNewFormat = nsiter->second; //Must have same target, e.g. OBMol, as current format if(pNewFormat->GetType() == pFormat->GetType()) { _LookingForNamespace=false; _SkipNextRead=true; SetInFormat(pNewFormat); pNewFormat->ReadMolecule(pOb,this); return true; } } } } const xmlChar* pname = xmlTextReaderConstLocalName(_reader); int typ = xmlTextReaderNodeType(_reader); if(typ==XML_READER_TYPE_SIGNIFICANT_WHITESPACE || !pname) continue; //Text nodes handled in format class string ElName((const char*)pname); //Pass the node on to the appropriate format class bool ret; if(typ==XML_READER_TYPE_ELEMENT) ret= pFormat->DoElement(ElName); else if(typ==XML_READER_TYPE_END_ELEMENT) ret= pFormat->EndElement(ElName); else continue; _lastpos = GetInStream()->tellg(); if(!ret) //derived format callback has stopped processing by returning false; //leave reader intact so it can be continued to be used. if(!IsOption("n",OBConversion::INOPTIONS)) { _LookingForNamespace = true; return true; } } if(result==-1) { xmlError* perr = xmlGetLastError(); if(perr && perr->level!=XML_ERR_NONE) { obErrorLog.ThrowError("XML Parser " + GetInFilename(), perr->message, obError); } xmlResetError(perr); GetInStream()->setstate(ios::eofbit); return false; } return GetInStream()->good() && result!=0; }
const std::string constants::Namespace(const std::string &id) { return Namespaces().find(id)->second; }