Version: 9.16.0
xmlParserBase.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
2//
3// This library is free software; you can redistribute it and/or
4// modify it under the terms of the GNU Lesser General Public
5// License as published by the Free Software Foundation; either
6// version 2.1 of the License, or (at your option) any later version.
7//
8// This library is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Lesser General Public License for more details.
12//
13// You should have received a copy of the GNU Lesser General Public
14// License along with this library; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#include "xmlParserBase.hxx"
21#include "Exception.hxx"
22
23#include <stdexcept>
24#include <iostream>
25#include <cstdarg>
26#include <cstdio>
27#include <cassert>
28
29//#define _DEVDEBUG_
30#include "YacsTrace.hxx"
31
32extern "C"
33{
34#include <libxml/parserInternals.h> // for xmlCreateFileParserCtxt
35}
36_xmlParserCtxt* xmlParserBase::_xmlParser;
37void xmlParserBase::XML_SetUserData(_xmlParserCtxt* ctxt,
38 xmlParserBase* parser)
39{
40 ctxt->userData = parser;
41}
42
43// --- generic part -----------------------------------------------------------
44
45using namespace std;
46using YACS::Exception;
47
48std::stack<xmlParserBase*> xmlParserBase::_stackParser;
49std::list<xmlParserBase*> xmlParserBase::_garbage;
50
55{
56 //DEBTRACE("xmlParserBase::start_document");
57 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
58}
59
64{
65 //DEBTRACE("xmlParserBase::end_document");
66 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
67}
68
73 const xmlChar* name,
74 const xmlChar** p)
75{
76 //DEBTRACE("xmlParserBase::start_element " << name);
78 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
79 const XML_Char *aName = tochar(name);
80 currentParser->incrCount(aName);
81 currentParser->onStart(aName, p);
82}
83
84
89 const xmlChar* name)
90{
91 //DEBTRACE("xmlParserBase::end_element");
92 const XML_Char *aName = tochar(name);
93 xmlParserBase *childParser = static_cast<xmlParserBase *> (userData);
94 _garbage.push_back(_stackParser.top());
95 DEBTRACE("xmlParserBase::end_element " << _garbage.size());
96 _stackParser.pop();
98 childParser->onEnd(aName);
99 childParser->end();
100 }
101
102
109 const xmlChar* ch,
110 int len)
111{
112 //DEBTRACE("xmlParserBase::characters " << len);
113 xmlParserBase *currentParser = (xmlParserBase *) (userData);
114 string data((char*)ch,len);
115 currentParser->charData(data);
116}
117
118
122void XMLCALL xmlParserBase::comment (void* userData,
123 const xmlChar* value)
124{
125 //DEBTRACE("xmlParserBase::comment");
126 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
127}
128
129
133void XMLCALL xmlParserBase::warning (void* userData,
134 const char* fmt, ...)
135{
136 DEBTRACE("xmlParserBase::warning");
137 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
138 va_list args;
139 va_start(args, fmt);
140 string format = "%s";
141 if (format == fmt)
142 {
143 char* parv;
144 parv = va_arg(args, char*);
145 cerr << parv ;
146 }
147 else cerr << __FILE__ << " [" << __LINE__ << "] : "
148 << "error format not taken into account: " << fmt << endl;
149 va_end(args);
150}
151
152
156void XMLCALL xmlParserBase::error (void* userData,
157 const char* fmt, ...)
158{
159 DEBTRACE("xmlParserBase::error");
160 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
161 va_list args;
162 va_start(args, fmt);
163 string format = "%s";
164 if (format == fmt)
165 {
166 char* parv;
167 parv = va_arg(args, char*);
168 cerr << parv ;
169 xmlParserBase *currentParser = (xmlParserBase *) userData;
170 //cerr << currentParser->element << endl;
171 }
172 else cerr << __FILE__ << " [" << __LINE__ << "] : "
173 << "error format not taken into account: " << fmt << endl;
174 va_end(args);
175}
176
177
182 const char* fmt, ...)
183{
184 DEBTRACE("xmlParserBase::fatal_error");
185 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
186 va_list args;
187 va_start(args, fmt);
188 string format = "%s";
189 if (format == fmt)
190 {
191 char* parv;
192 parv = va_arg(args, char*);
193 cerr << parv ;
194 }
195 else cerr << __FILE__ << " [" << __LINE__ << "] : "
196 << "error format not taken into account: " << fmt << endl;
197 va_end(args);
198}
199
205 const xmlChar* value,
206 int len)
207{
208 //DEBTRACE("xmlParserBase::cdata_block");
209 xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
210 string data((char*)value,len);
211 currentParser->charData(data);
212}
213
215{
216 while (!_garbage.empty())
217 {
218 delete (_garbage.front());
219 _garbage.pop_front();
220 }
221}
222
227void xmlParserBase::getAttributes(const xmlChar** p)
228{
229 if (p) while (*p)
230 {
231 string attributeName = (char*)*p;
232 //cerr << "attribute name " << attributeName << endl;
233 p++;
234 string attributeValue = (char*)*p;
235 //cerr << "attribute value " << attributeValue << endl;
236 p++;
237 _mapAttrib[attributeName] = attributeValue;
238 }
239}
240
245void xmlParserBase::setAttribute(std::string key, std::string value)
246{
247 _mapAttrib[key] = value;
248}
249
254std::string xmlParserBase::getAttribute(std::string key)
255{
256 if (_mapAttrib.find(key) == _mapAttrib.end())
257 {
258 string what = "Attribute does not exist: " + key;
259 throw Exception(what);
260 }
261 return _mapAttrib[key];
262}
263
267void xmlParserBase::addData(std::string value)
268{
269 // DEBTRACE("xmlParserBase::addData()");
270 _data += value;
271}
272
277void xmlParserBase::init (const xmlChar** p, xmlParserBase* father)
278{
279 _father = father;
280}
281
285void xmlParserBase::onStart (const XML_Char* elem, const xmlChar** p)
286{
287}
288
293{
294}
295
299void xmlParserBase::charData (std::string data)
300{
301}
302
308{
309 if(counts.find(elem)==counts.end())
310 counts[elem]=1;
311 else
312 counts[elem]=counts[elem]+1;
313}
314
319{
320}
321
325void xmlParserBase::stopParse(std::string what)
326{
327 xmlStopParser(_xmlParser);
328}
329
330// ----------------------------------------------------------------------------
331
336xmlReader::xmlReader(xmlParserBase* parser): _rootParser(parser)
337{
338}
339
344void xmlReader::parse(std::string xmlFile)
345{
346 _rootParser->init(0);
348
349 xmlSAXHandler baseHandler =
350 {
351 0, // internal_subset,
352 0, // isStandalone
353 0, // hasInternalSubset
354 0, // hasExternalSubset
355 0, // resolveEntity
356 0, // getEntity
357 0, // entityDecl
358 0, // notationDecl
359 0, // attributeDecl
360 0, // elementDecl
361 0, // unparsedEntityDecl
362 0, // setDocumentLocator
363 xmlParserBase::start_document, // startDocument
364 xmlParserBase::end_document, // endDocument
365 xmlParserBase::start_element, // startElement
366 xmlParserBase::end_element, // endElement
367 0, // reference
368 xmlParserBase::characters, // characters
369 0, // ignorableWhitespace
370 0, // processingInstruction
371 xmlParserBase::comment, // comment
372 xmlParserBase::warning, // warning
373 xmlParserBase::error, // error
374 xmlParserBase::fatal_error, // fatalError
375 0, // getParameterEntity
376 xmlParserBase::cdata_block, // cdataBlock
377 0 // externalSubset
378 };
379
380 // --- sequence from libxml++, to have a libxml context
381
382 _xmlParserCtxt* saxContext;
383 saxContext = xmlCreateFileParserCtxt(xmlFile.c_str());
384 if (!saxContext)
385 {
387 string what = "problem while trying to open the file for parsing " + xmlFile;
388 throw Exception(what);
389 }
390 xmlSAXHandlerPtr old_sax = saxContext->sax;
391 saxContext->sax = &baseHandler;
393 saxContext->userData = _rootParser;
394
395 xmlParseDocument(saxContext);
397 if ( saxContext->myDoc != NULL ) {
398 xmlFreeDoc( saxContext->myDoc );
399 saxContext->myDoc = NULL;
400 }
401 if ( saxContext != NULL ) {
402 saxContext->sax = old_sax;
403 xmlFreeParserCtxt( saxContext );
404 }
405 DEBTRACE("xmlParserBase::end of parse, garbage size = " << _rootParser->getGarbageSize());
406}
407
408// ----------------------------------------------------------------------------
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
base class for xml parsers, runtime independant
static void XML_SetUserData(_xmlParserCtxt *ctxt, xmlParserBase *parser)
virtual void onStart(const XML_Char *elem, const xmlChar **p)
static void XMLCALL start_element(void *userData, const xmlChar *name, const xmlChar **p)
static int getGarbageSize()
virtual void end()
virtual void stopParse(std::string what)
static void XMLCALL end_element(void *userData, const xmlChar *name)
static void XMLCALL start_document(void *userData)
static void XMLCALL characters(void *userData, const xmlChar *ch, int len)
static _xmlParserCtxt * _xmlParser
xmlParserBase * _father
static void XMLCALL error(void *userData, const char *fmt,...)
std::string _data
virtual void addData(std::string value)
static void XMLCALL fatal_error(void *userData, const char *fmt,...)
virtual void onEnd(const XML_Char *name)
static std::list< xmlParserBase * > _garbage
void setAttribute(std::string key, std::string value)
static void cleanGarbage()
static std::stack< xmlParserBase * > _stackParser
std::map< std::string, std::string > _mapAttrib
void getAttributes(const xmlChar **p)
static void XMLCALL comment(void *userData, const xmlChar *value)
static void XMLCALL cdata_block(void *userData, const xmlChar *value, int len)
virtual void init(const xmlChar **p, xmlParserBase *father=0)
std::string getAttribute(std::string key)
static void XMLCALL end_document(void *userData)
static void XMLCALL warning(void *userData, const char *fmt,...)
virtual void charData(std::string data)
std::map< std::string, int > counts
virtual void incrCount(const XML_Char *elem)
virtual void parse(std::string xmlFile)
xmlParserBase * _rootParser
xmlReader(xmlParserBase *parser)
Proc * p
Definition: driver.cxx:216
_xmlParserCtxt * saxContext
Definition: parserBase.cxx:31
XML_Char * tochar(const xmlChar *c)
#define XML_Char
#define XMLCALL