#ifndef __XMLIO_XML_NODE__ #define __XMLIO_XML_NODE__ // Entêtes Poco DOM #include #include #include #include //#include // Entêtes Poco SAX #include // Utilisation de la STL using std::string; using std::pair; using std::vector; using std::deque; using std::istream; using std::ostream; using std::ostringstream; using std::ifstream; // Utilisation de la biliothèque POCO using Poco::XML::DOMParser; using Poco::XML::InputSource; using Poco::XML::Document; using Poco::XML::Node; using Poco::XML::Element; using Poco::XML::NamedNodeMap; using Poco::HashMap; namespace XMLIOSERVER { namespace XML { typedef HashMap THashAttributes; // TODO Mettre des auto_ptr ici car gestion de la mémoire lamentable sans. typedef Document* PDocument; typedef Node* PNode; class XMLNode { protected : XMLNode(const string& _rootName) : rootName(_rootName) { this->cNode = NULL ; } public : static XMLNode CreateNode(istream& _istr, const string& _rootName = string("simulation")) { XMLNode node(_rootName); if ((_istr.good())) { // S'il est possible de lire le flux en entrée ... InputSource src(_istr); DOMParser parser; // On parse la source XML et on vérifie que le premier noeud (racine) est du type "Element" // ... et à pour valeur la chaîne rootName. PDocument pDoc = parser.parse(&src); if (!(pDoc->documentElement()->nodeName().compare(_rootName))) { node.cNode = pDoc->documentElement(); node.goToChildElement(); } else { ostringstream oss; oss << "L'élément racine doit avoir pour valeur <" << _rootName << "> (\"" << (pDoc->documentElement()->nodeName()) <<"\" lue)"; throw XMLParsingException(oss.str()); } } else throw XMLIOStreamException("Impossible de lire le flux en entrée pour le parsing XML !"); return (node); } string getElementName(void) const {return (this->cNode->nodeName());} bool goToNextElement(Node* nextElement = 0) { nextElement = (!nextElement)? this->cNode->nextSibling() : nextElement; // On parcourt la liste des "siblings" jusqu'à trouver un élément quelconque. for(; ; nextElement = nextElement->nextSibling()) if (nextElement == NULL) break; else if (nextElement->nodeType() == 1) {// Si l'un des noeuds est un élément... this->cNode = nextElement ; return (true); } return (false); } bool goToChildElement(void) { // On parcourt la liste des enfants jusqu'à trouver un élément quelconque. if (this->cNode->firstChild()) if (this->goToNextElement(this->cNode->firstChild())) return (true); return (false); } bool goToParentElement(void) { // Pas de retour au parent si on est à la racine. if (!(this->getElementName().compare(rootName))) return (false); this->cNode = this->cNode->parentNode(); return (true); } bool getAttributes(THashAttributes& attributes) const { if(!this->cNode->hasAttributes()) return (false); NamedNodeMap* map = this->cNode->attributes(); for(unsigned int i = 0; i< map->length(); i++) attributes[map->item(i)->nodeName()] = map->item(i)->nodeValue(); return (true); } ~XMLNode() { /* Ne rien faire de plus */ } private : PNode cNode; string rootName; };// class XMLNode }; // namespace XML };// namespace XMLIOSERVER #endif // __XMLIO_XML_NODE__