///////////////////////////////////////////////////////////////////////////// // fuzzyanalyzer.cc // // SIMLIB version: 2.16.3 // Date: 2001-05-24 // Copyright (c) 1999-2001 David Martinek, Dr. Ing. Petr Peringer // // This library is licensed under GNU Library GPL. See the file COPYING. // // Warning: this is EXPERIMENTAL code, interfaces can be changed // // Fuzzy subsystem for SIMLIB // version 1 --- Th may 24 18:33:52 CEST 2001 // ///////////////////////////////////////////////////////////////////////////// // Implementation of fuzzy XML analyzer according to SAX2. // For this module Xerces 1.3 library is needed. ///////////////////////////////////////////////////////////////////////////// //#include #include #include #include "simlib.h" #include #include "fuzzyanalyzer.h" #include #include #include #include /** * It analyzes file with xml definition of fuzzy model. XML file must have the same format * as MeFE program uses.
* Analyzuje soubor, který obsahuje xml definici fuzzy modelu. XML musí být stejného * formátu jako používá program MeFE. * @param fileName Name of file with XML data.
Jméno souboru s XML daty. */ void FuzzyAnalyzer::analyze(char * fileName) { try { XMLPlatformUtils::Initialize(); handler.init(); } catch(const XMLException& e) { StrX emsg(e.getMessage()); SIMLIB_error(emsg.toAscii()); } SAX2XMLReader * parser = XMLReaderFactory::createXMLReader(); parser->setFeature(XMLString::transcode("http://xml.org/sax/features/validation"), validation); parser->setFeature(XMLString::transcode("http://xml.org/sax/features/namespaces"), nameSpaces); parser->setFeature(XMLString::transcode("http://apache.org/xml/features/validation/dynamic"), false); try { parser->setContentHandler(&handler); parser->setErrorHandler(&handler); const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis(); parser->parse(fileName); const unsigned long stopMillis = XMLPlatformUtils::getCurrentMillis(); analyzeTime = stopMillis - startMillis; data = handler.getData(); } catch(const XMLException& e) { StrX emsg(e.getMessage()); SIMLIB_error(emsg.toAscii()); } delete parser; XMLPlatformUtils::Terminate(); } /** * It returns data obtained by analysis. Product can be retyped into FuzzyData type.
* Vrátí data získaná analýzou. Výsledek je možné přetypovat na FuzzyData. */ AnalyzedData * FuzzyAnalyzer::getAnalyzedData() { return data; } ///////////////////////////////////////////////////////////////////////////////////// // // FuzzyHandler // ///////////////////////////////////////////////////////////////////////////////////// /** * It set all variables into their default values.
* Nastaví implicitní hodnoty všech vnitřních proměnných. */ void FuzzyHandler::init() { fSawErrors = false; errors = 0; fatalErrors = 0; warnings = 0; in1 = NULL; in2 = NULL; out = NULL; rules = NULL; data = NULL; fset = NULL; mf = NULL; isClass = false; } // --------------------------------------------------------------------------- // fuzzyhandler: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- /** Start document event treatment.
Ošetření události začátku dokumentu. */ void FuzzyHandler::startDocument() { // cout << "startDocument" << endl; numSets = 0; numRows = 0; rowLength = 0; } /** Start element event treatment.
Ošetření události výskytu začátku elementu. */ void FuzzyHandler::startElement(const XMLCh* const uri , const XMLCh* const localname , const XMLCh* const qname , const Attributes& attrs) { // Nikdo tuto metodu v zájmu svého duševního zdraví NEZKOUMEJTE, protože je delší než je zdrávo. // Autor. errno = 0; SAXParseException *spe; //cout << "startElement" << endl; StrX *local = new StrX(localname); if (local->equals("fuzzyclass")) { isClass = true; } else if (local->equals("fuzzytype")) { StrX *parameter = new StrX("minrange"); StrX *value = new StrX(attrs.getValue(parameter->toUnicode())); //cout << "toUnicode(), *locator); error(*spe); delete parameter; throw spe; } parameter->setValue("maxrange"); value->setValue(attrs.getValue(parameter->toUnicode())); //cout << " maxrange=" << value->toAscii(); double max = strtod(value->toAscii(), (char**)NULL); if (errno != 0) { value->setValue("Bad number format for attribute \"maxrange\"!"); spe = new SAXParseException(value->toUnicode(), *locator); error(*spe); delete parameter; throw spe; } parameter->setValue("typename"); value->setValue(attrs.getValue(parameter->toUnicode())); //cout << "typename=" << value->toAscii() << ">" << endl; fset = new FuzzySet(value->toAscii(), min, max); delete parameter; delete value; } else if (local->equals("fuzzymf")) { StrX* mftype = new StrX("mftype"); mftype->setValue(attrs.getValue(mftype->toUnicode())); StrX* wordvalue = new StrX("wordvalue"); wordvalue->setValue(attrs.getValue(wordvalue->toUnicode())); try { //cout << "" << endl; mf = MFFactory::create(mftype->toAscii(), wordvalue->toAscii()); } catch(const MFFException& e) { wordvalue->setValue(e.getMsg()); spe = new SAXParseException(wordvalue->toUnicode(), *locator); error(*spe); delete mftype; throw spe; } delete mftype; delete wordvalue; } else if (local->equals("value")) { StrX * value = new StrX("value"); value->setValue(attrs.getValue(value->toUnicode())); //cout << "" << endl; double val = strtod(value->toAscii(), (char**)NULL); if (errno != 0) { value->setValue("Bad number format for attribute \"value\"!"); spe = new SAXParseException(value->toUnicode(), *locator); error(*spe); throw spe; } mf->addDefValue(val); delete value; } else if (local->equals("behavior")) { //cout << "" << endl; rules = new FuzzyIIORules(in1, in2, out); } else if (local->equals("row")) { //cout << "" << endl; numRows++; rowLength = 0; } else if (local->equals("outvalue")) { rowLength++; StrX *value = new StrX("value"); value->setValue(attrs.getValue(value->toUnicode())); //cout << "" << endl; rules->add(FuzzyIIORules::opAND, rowLength-1, numRows-1, value->toAscii()); } delete local; // fElementCount++; // fAttrCount += attrs.getLength(); } /** End element event treatment.
Ošetření události výskytu konce elementu. */ void FuzzyHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { //cout << "endElement" << endl; SAXParseException *spe; StrX * local = new StrX(localname); if (local->equals("fuzzymf")) { fset->add(*mf); delete mf; mf = NULL; } else if (local->equals("fuzzytype")) { if (isClass) { switch (numSets++) { case 0: in1 = new FuzzyInput(*(this->fset)); break; case 1: in2 = new FuzzyInput(*fset); break; case 2: out = new FuzzyOutput(*fset); break; default: break; } delete fset; fset = NULL; } else { data = new FuzzyData(fset); } } else if (local->equals("row")) { if (rowLength != in1->count()) { local->setValue("Bad count of \"outvalue\" tags!"); spe = new SAXParseException(local->toUnicode(), *locator); error(*spe); throw spe; } } else if (local->equals("behavior")) { if (numRows != in2->count()) { local->setValue("Bad count of \"rows\" tags!"); spe = new SAXParseException(local->toUnicode(), *locator); error(*spe); throw spe; } } else if (local->equals("fuzzyclass")) { data = new FuzzyData(in1, in2, out, rules); } delete local; } // --------------------------------------------------------------------------- // FuzzyHandler: Overrides of the SAX ErrorHandler interface // --------------------------------------------------------------------------- /** Printout of error message.
Výpis chybového hlášení. */ void FuzzyHandler::error(const SAXParseException& e) { fSawErrors = true; errors++; cerr << "\nError at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "\n Message: " << StrX(e.getMessage()) << endl; } /** Printout of fatal error message.
Výpis chybového hlášení při fatální chybě. */ void FuzzyHandler::fatalError(const SAXParseException& e) { fSawErrors = true; fatalErrors++; cerr << "\nFatal Error at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "\n Message: " << StrX(e.getMessage()) << endl; } /** Printout of warnning.
Výpis varování. */ void FuzzyHandler::warning(const SAXParseException& e) { warnings++; cerr << "\nWarning at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char " << e.getColumnNumber() << "\n Message: " << StrX(e.getMessage()) << endl; }