source: XMLIO_V2/dev/dev_rv/xmlio_xml_parser.hpp @ 88

Last change on this file since 88 was 88, checked in by hozdoba, 14 years ago

Version expérimentale, commit pour sauvegarde.

File size: 6.1 KB
Line 
1#ifndef __XMLIO_XML_PARSER__
2#define __XMLIO_XML_PARSER__
3
4// Entêtes Poco DOM
5#include <Poco/DOM/DOMParser.h>
6#include <Poco/DOM/Document.h>
7#include <Poco/DOM/Element.h>
8
9#include <Poco/DOM/NamedNodeMap.h>
10
11//#include <Poco/DOM/AutoPtr.h>
12
13// Entêtes Poco SAX
14#include <Poco/SAX/InputSource.h>
15
16// Utilisation de la STL
17using std::string;
18
19using std::pair;
20using std::vector;
21using std::deque;
22
23using std::istream;
24using std::ostream;
25using std::ostringstream;
26using std::ifstream;
27
28// Utilisation de la biliothÚque POCO
29using Poco::XML::DOMParser;
30using Poco::XML::InputSource;
31
32using Poco::XML::Document;
33using Poco::XML::Node;
34using Poco::XML::Element;
35
36using Poco::XML::NamedNodeMap;
37
38using Poco::HashMap;
39
40namespace XMLIOSERVER
41{
42   namespace XML
43   {
44     
45      typedef HashMap<string, string> THashAttributes;
46         
47      // TODO Mettre des auto_ptr ici car gestion de la mémoire lamentable sans.
48      typedef Document* PDocument;
49      typedef Node*     PNode;
50         
51      class XMLNode
52      {
53         protected :
54           
55            XMLNode(const string& _rootName) : rootName(_rootName) { this->cNode = NULL ; }
56           
57         public :
58           
59            static XMLNode CreateNode(istream& _istr, const string& _rootName = string("simulation"))
60            {
61               XMLNode node(_rootName);
62                 
63               if ((_istr.good()))
64               { // S'il est possible de lire le flux en entrée ...
65                  InputSource src(_istr);
66                  DOMParser parser;
67                     
68                  // On parse la source XML et on vérifie que le premier noeud (racine) est du type "Element"
69                  // ... et à pour valeur la chaîne rootName.
70                  PDocument pDoc = parser.parse(&src);
71                  if (!(pDoc->documentElement()->nodeName().compare(_rootName)))
72                  {
73                     node.cNode = pDoc->documentElement();
74                     node.goToChildElement();
75                  }
76                  else
77                  {
78                     ostringstream oss;
79                     oss << "L'élément racine doit avoir pour valeur <" << _rootName << "> (\"" <<  (pDoc->documentElement()->nodeName()) <<"\" lue)";
80                     throw XMLParsingException(oss.str());
81                  }   
82               }
83               else
84                  throw XMLIOStreamException("Impossible de lire le flux en entrée pour le parsing XML !");
85                 
86               return (node);
87            }
88               
89            string getElementName(void) const {return (this->cNode->nodeName());}
90               
91            bool goToNextElement(Node* nextElement = 0) 
92            {
93               nextElement = (!nextElement)? this->cNode->nextSibling() : nextElement;
94             
95               // On parcourt la liste des "siblings" jusqu'à trouver un élément quelconque.
96               for(; ; nextElement = nextElement->nextSibling())
97               if (nextElement == NULL) break;
98               else if (nextElement->nodeType() == 1)
99               {// Si l'un des noeuds est un élément...
100                this->cNode = nextElement ;
101                return (true);
102               } 
103              return (false);
104             }
105             
106             bool goToChildElement(void)
107             {
108              // On parcourt la liste des enfants jusqu'à trouver un élément quelconque.
109              if (this->cNode->firstChild())
110               if (this->goToNextElement(this->cNode->firstChild()))
111                return (true);
112               
113              return (false);
114             }
115             
116             bool goToParentElement(void)
117             { 
118              // Pas de retour au parent si on est à la racine.
119              if (!(this->getElementName().compare(rootName))) return (false);
120              this->cNode = this->cNode->parentNode();
121              return (true);
122             }
123             
124             bool getAttributes(THashAttributes& attributes) const
125             {
126              if(!this->cNode->hasAttributes()) return (false);
127              NamedNodeMap* map = this->cNode->attributes();
128             
129              for(unsigned int i = 0; i< map->length(); i++)
130               attributes[map->item(i)->nodeName()] = map->item(i)->nodeValue();
131
132              return (true);
133             }
134           
135            ~XMLNode() 
136            { /* Ne rien faire de plus */ }
137
138         private :
139                 
140            PNode  cNode;
141            string rootName;     
142         
143      };// class XMLNode
144     
145      #include "field.hpp"
146     
147      #include "xmlio_group_template.hpp"     
148      #include "field_group.hpp"
149     
150      #include "context.hpp"
151           
152      using XMLIOSERVER::Context;
153     
154      class XMLParser
155      {
156         public : 
157            static void Parse(XMLNode& _node)
158            {
159               THashAttributes attributes;
160               
161              do {               
162                 // Traitement de l'identifiant
163                  _node.getAttributes(attributes);           
164                  if (attributes.end() == attributes.find("id"))
165                  { WARNING("L'un des contexts ne sera pas traité car il n'est pas identifié !"); continue; }
166                  Context& context = Context::CreateObject(attributes["id"]);
167                  context.parse(_node);
168                  attributes.clear();
169                 
170               } while (_node.goToNextElement());               
171            }   
172           
173            static bool CLASS_TEST(ostream& log = std::clog)
174            {
175               ifstream istr( "/local/testsuite/iodef_test.xml" , ifstream::in ); // Modifier le répertoire de test ici
176               XMLNode node = XMLNode::CreateNode(istr);
177               XMLParser::Parse(node);
178               log << "Nombre de contexts listés : " << Context::GetCurrentListObject().getSize() << " contre 2 attendus."<< std::endl;
179               log << "Test  XMLParser ... ok !" << std::endl;
180               return (true);
181            }
182                 
183      }; // class XMLParser     
184   }; // namespace XML
185
186};// namespace XMLIOSERVER
187
188
189#endif // __XMLIO_XML_PARSER__
Note: See TracBrowser for help on using the repository browser.