ROOT  6.06/09
Reference Guide
TSAXParser.cxx
Go to the documentation of this file.
1 // @(#)root/xmlparser:$Id$
2 // Author: Jose Lo 12/1/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**
13 \class TSAXParser
14 \ingroup IO
15 
16 TSAXParser is a subclass of TXMLParser, it is a wraper class to
17 libxml library.
18 SAX (Simple API for XML) is an event based interface, which doesn't
19 maintain the DOM tree in memory, in other words, it's much more
20 efficient for large document.
21 TSAXParserCallback contains a number of callback routines to the
22 parser in a xmlSAXHandler structure. The parser will then parse the
23 document and call the appropriate callback when certain conditions
24 occur.
25 */
26 
27 /*************************************************************************
28  This source is based on libxml++, a C++ wrapper for the libxml XML
29  parser library.Copyright (C) 2000 by Ari Johnson
30 
31  libxml++ are copyright (C) 2000 by Ari Johnson, and are covered by the
32  GNU Lesser General Public License, which should be included with
33  libxml++ as the file COPYING.
34  *************************************************************************/
35 
36 #include "TSAXParser.h"
37 #include "TXMLAttr.h"
38 #include "Varargs.h"
39 #include "TObjString.h"
40 #include "TList.h"
41 #include "TClass.h"
42 
43 #include <libxml/parser.h>
44 #include <libxml/parserInternals.h>
45 
46 
47 class TSAXParserCallback {
48 public:
49  static void StartDocument(void *fParser);
50  static void EndDocument(void *fParser);
51  static void StartElement(void *fParser, const xmlChar *name, const xmlChar **p);
52  static void EndElement(void *fParser, const xmlChar *name);
53  static void Characters(void *fParser, const xmlChar *ch, Int_t len);
54  static void Comment(void *fParser, const xmlChar *value);
55  static void CdataBlock(void *fParser, const xmlChar *value, Int_t len);
56  static void Warning(void *fParser, const char *fmt, ...);
57  static void Error(void *fParser, const char *fmt, ...);
58  static void FatalError(void *fParser, const char *fmt, ...);
59 };
60 
61 
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Create SAX parser.
66 
68 {
69  fSAXHandler = new xmlSAXHandler;
70  memset(fSAXHandler, 0, sizeof(xmlSAXHandler));
71 
72  fSAXHandler->startDocument =
73  (startDocumentSAXFunc)TSAXParserCallback::StartDocument;
74  fSAXHandler->endDocument =
75  (endDocumentSAXFunc)TSAXParserCallback::EndDocument;
76  fSAXHandler->startElement =
77  (startElementSAXFunc)TSAXParserCallback::StartElement;
78  fSAXHandler->endElement =
79  (endElementSAXFunc)TSAXParserCallback::EndElement;
80  fSAXHandler->characters =
81  (charactersSAXFunc)TSAXParserCallback::Characters;
82  fSAXHandler->comment =
83  (commentSAXFunc)TSAXParserCallback::Comment;
84  fSAXHandler->cdataBlock =
85  (cdataBlockSAXFunc)TSAXParserCallback::CdataBlock;
86  fSAXHandler->warning =
87  (warningSAXFunc)TSAXParserCallback::Warning;
88  fSAXHandler->error =
89  (errorSAXFunc)TSAXParserCallback::Error;
90  fSAXHandler->fatalError =
91  (fatalErrorSAXFunc)TSAXParserCallback::FatalError;
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// TSAXParser desctructor
96 
98 {
100 
101  delete fSAXHandler;
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Emit a signal for OnStartDocument.
106 
108 {
109  Emit("OnStartDocument()");
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Emit a signal for OnEndDocument.
114 
116 {
117  Emit("OnEndDocument()");
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Emit a signal for OnStarElement, where name is the Element's name and
122 /// attribute is a TList of (TObjString*, TObjString *) TPair's.
123 /// The TPair's key is the attribute's name and value is the attribute's
124 /// value.
125 
126 void TSAXParser::OnStartElement(const char *name, const TList *attributes)
127 {
128  Long_t args[2];
129  args[0] = (Long_t)name;
130  args[1] = (Long_t)attributes;
131 
132  Emit("OnStartElement(const char *, const TList *)", args);
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// Emit a signal for OnEndElement, where name is the Element's name.
137 
138 void TSAXParser::OnEndElement(const char *name)
139 {
140  Emit("OnEndElement(const char *)", name);
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Emit a signal for OnCharacters, where characters are the characters
145 /// outside of tags.
146 
147 void TSAXParser::OnCharacters(const char *characters)
148 {
149  Emit("OnCharacters(const char *)", characters);
150 }
151 
152 ////////////////////////////////////////////////////////////////////////////////
153 /// Emit a signal for OnComment, where text is the comment.
154 
155 void TSAXParser::OnComment(const char *text)
156 {
157  Emit("OnComment(const char *)", text);
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Emit a signal for OnWarning, where text is the warning.
162 
163 void TSAXParser::OnWarning(const char *text)
164 {
165  Emit("OnWarning(const char *)", text);
166 }
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 /// Emit a signal for OnError, where text is the error and it returns the
170 /// Parse Error Code, see TXMLParser.
171 
173 {
174  Emit("OnError(const char *)", text);
175  return -3;
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// Emit a signal for OnFactalError, where text is the error and it
180 /// returns the Parse Error Code, see TXMLParser.
181 
183 {
184  Emit("OnFatalError(const char *)", text);
185  return -4;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Emit a signal for OnCdataBlock.
190 
191 void TSAXParser::OnCdataBlock(const char *text, Int_t len)
192 {
193  Long_t args[2];
194  args[0] = (Long_t)text;
195  args[1] = len;
196 
197  Emit("OnCdataBlock(const char *, Int_t)", args);
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// This function parses the xml file, by initializing the parser and checks
202 /// whether the parse context is created or not, it will check as well
203 /// whether the document is well formated.
204 /// It returns the parse error code, see TXMLParser.
205 
207 {
208  if (!fContext) {
209  return -2;
210  }
211 
212  xmlSAXHandlerPtr oldSAX = fContext->sax;
213  fContext->sax = fSAXHandler;
214  fContext->userData = this;
215 
217 
218  xmlParseDocument(fContext);
219 
220  fContext->sax = oldSAX;
221 
222  if (!fContext->wellFormed && fParseCode == 0) {
223  fParseCode = -5;
224  }
225 
227 
228  return fParseCode;
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// It creates the parse context of the xml file, where the xml file name is
233 /// filename. If context is created sucessfully, it will call Parse()
234 /// It returns parse error code, see TXMLParser.
235 
237 {
238  // Attempt to parse a second file while a parse is in progress.
239  if (fContext) {
240  return -1;
241  }
242 
243  fContext = xmlCreateFileParserCtxt(filename);
244  return Parse();
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// It parse the contents, instead of a file.
249 /// It will return error if is attempted to parse a second file while
250 /// a parse is in progres.
251 /// It returns parse code error, see TXMLParser.
252 
253 Int_t TSAXParser::ParseBuffer(const char *contents, Int_t len)
254 {
255  // Attempt to parse a second file while a parse is in progress.
256  if (fContext) {
257  return -1;
258  }
259 
260  fContext = xmlCreateMemoryParserCtxt(contents, len);
261  return Parse();
262 }
263 
264 
265 //--- TSAXParserCallback -------------------------------------------------------
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// StartDocument Callback function.
269 
270 void TSAXParserCallback::StartDocument(void *fParser)
271 {
272  TSAXParser *parser = (TSAXParser*)fParser;
273  parser->OnStartDocument();
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// EndDocument callback function.
278 
279 void TSAXParserCallback::EndDocument(void *fParser)
280 {
281  TSAXParser *parser = (TSAXParser*)fParser;
282  parser->OnEndDocument();
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// StartElement callback function, where name is the name of the element
287 /// and p contains the attributes for the start tag.
288 
289 void TSAXParserCallback::StartElement(void *fParser, const xmlChar *name,
290  const xmlChar **p)
291 {
292  TSAXParser *parser = (TSAXParser*)fParser;
293  TList *attributes = new TList;
294 
295  if (p) {
296  for (const xmlChar **cur = p; cur && *cur; cur += 2) {
297  attributes->Add(new TXMLAttr((const char*)*cur,
298  (const char*)*(cur + 1)));
299  }
300  }
301 
302  parser->OnStartElement((const char*) name, attributes);
303 
304  attributes->Delete();
305  delete attributes;
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// EndElement callback function, where name is the name of the element.
310 
311 void TSAXParserCallback::EndElement(void *fParser, const xmlChar *name)
312 {
313  TSAXParser *parser = (TSAXParser*)fParser;
314  parser->OnEndElement((const char*) name);
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Character callback function. It is called when there are characters that
319 /// are outside of tags get parsed and the context will be stored in ch,
320 /// len is the length of ch.
321 
322 void TSAXParserCallback::Characters(void *fParser, const xmlChar *ch,
323  Int_t len)
324 {
325  TSAXParser *parser = (TSAXParser*)fParser;
326 
327  char *str = new char[len+1];
328  strlcpy(str, (const char*) ch, len+1);
329  str[len] = '\0';
330 
331  parser->OnCharacters(str);
332 
333  delete [] str;
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Comment callback function.
338 /// Comment of the xml file will be parsed to value.
339 
340 void TSAXParserCallback::Comment(void *fParser, const xmlChar *value)
341 {
342  TSAXParser *parser = (TSAXParser*)fParser;
343  parser->OnComment((const char*) value);
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Warning callback function. Warnings while parsing a xml file will
348 /// be stored at fmt.
349 
350 void TSAXParserCallback::Warning(void * fParser, const char *va_(fmt), ...)
351 {
352  TSAXParser *parser = (TSAXParser*)fParser;
353 
354  va_list arg;
355  char buffer[2048];
356 
357  va_start(arg, va_(fmt));
358  vsnprintf(buffer, 2048, va_(fmt), arg);
359  va_end(arg);
360 
361  TString buff(buffer);
362 
363  parser->OnWarning(buff.Data());
364 }
365 
366 ////////////////////////////////////////////////////////////////////////////////
367 /// Error callback function. Errors while parsing a xml file will be stored
368 /// at fmt.
369 
370 void TSAXParserCallback::Error(void *fParser, const char *va_(fmt), ...)
371 {
372  Int_t errorcode;
373  TSAXParser *parser = (TSAXParser*)fParser;
374 
375  va_list arg;
376  char buffer[2048];
377 
378  va_start(arg, va_(fmt));
379  vsnprintf(buffer, 2048, va_(fmt), arg);
380  va_end(arg);
381 
382  TString buff(buffer);
383 
384  errorcode = parser->OnError(buff.Data());
385  if (errorcode < 0) { //When error occurs, write fErrorCode
386  parser->SetParseCode(errorcode);
387  }
388 
389  if (errorcode < 0 && parser->GetStopOnError()) {
390  //When GetStopOnError is enabled, stop the parse when an error occurs
391  parser->StopParser();
392  }
393 }
394 
395 ////////////////////////////////////////////////////////////////////////////////
396 /// FactalError callback function. Factal errors while parsing a xml file
397 /// will be stored at fmt.
398 
399 void TSAXParserCallback::FatalError(void *fParser, const char *va_(fmt), ...)
400 {
401  Int_t errorcode;
402  TSAXParser *parser = (TSAXParser*)fParser;
403 
404  va_list arg;
405  char buffer[2048];
406 
407  va_start(arg, va_(fmt));
408  vsnprintf(buffer, 2048, va_(fmt), arg);
409  va_end(arg);
410 
411  TString buff(buffer);
412 
413  errorcode = parser->OnFatalError(buff);
414  if (errorcode < 0) {
415  parser->SetParseCode(errorcode);
416  parser->StopParser();
417  }
418 }
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 /// CdataBlock Callback function.
422 
423 void TSAXParserCallback::CdataBlock(void *fParser, const xmlChar *value,
424  Int_t len)
425 {
426  TSAXParser *parser = (TSAXParser*)fParser;
427  parser->OnCdataBlock((const char*)value, len);
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// A default TSAXParser to a user-defined Handler connection function.
432 /// This function makes connection between various function from TSAXParser
433 /// with the user-define SAX Handler, whose functions has to be exactly the
434 /// same as in TSAXParser.
435 ///
436 /// \param[in] handler Name User-defined SAX Handler class name
437 /// \param[in] handler Pointer to the user-defined SAX Handler
438 ///
439 /// See SAXHandler.C tutorial.
440 
441 void TSAXParser::ConnectToHandler(const char *handlerName, void *handler)
442 {
443  const TString kFunctionsName [] = {
444  "OnStartDocument()",
445  "OnEndDocument()",
446  "OnStartElement(const char *, const TList *)",
447  "OnEndElement(const char *)",
448  "OnCharacters(const char *)",
449  "OnComment(const char *)",
450  "OnWarning(const char *)",
451  "OnError(const char *)",
452  "OnFatalError(const char *)",
453  "OnCdataBlock(const char *, Int_t)"
454  };
455 
456  TClass *cl = TClass::GetClass(handlerName);
457 
458  for (Int_t i = 0; i < 10; i++) {
459  if (CheckConnectArgs(this, this->IsA(), kFunctionsName[i],
460  cl, kFunctionsName[i]) != -1)
461  Connect(kFunctionsName[i], handlerName, handler, kFunctionsName[i]);
462  }
463 }
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:404
virtual void OnComment(const char *text)
Emit a signal for OnComment, where text is the comment.
Definition: TSAXParser.cxx:155
static Int_t CheckConnectArgs(TQObject *sender, TClass *sender_class, const char *signal, TClass *receiver_class, const char *slot)
Checking of consitency of sender/receiver methods/arguments.
Definition: TQObject.cxx:179
virtual void InitializeContext()
Initialize parser parameters, such as, disactivate non-standards libxml1 features, on/off validation, clear error and warning messages.
Definition: TXMLParser.cxx:153
virtual Int_t ParseBuffer(const char *contents, Int_t len)
It parse the contents, instead of a file.
Definition: TSAXParser.cxx:253
_xmlSAXHandler * fSAXHandler
libxml2 SAX handler
Definition: TSAXParser.h:30
TSAXParser is a subclass of TXMLParser, it is a wraper class to libxml library.
Definition: TSAXParser.h:25
virtual void OnStartDocument()
Emit a signal for OnStartDocument.
Definition: TSAXParser.cxx:107
static const char * filename()
virtual void ReleaseUnderlying()
To release any existing document.
Definition: TXMLParser.cxx:93
Int_t fParseCode
To keep track of the errorcodes.
Definition: TXMLParser.h:43
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
_xmlParserCtxt * fContext
Parse the xml file.
Definition: TXMLParser.h:37
virtual void OnWarning(const char *text)
Emit a signal for OnWarning, where text is the warning.
Definition: TSAXParser.cxx:163
virtual Int_t OnError(const char *text)
Emit a signal for OnError, where text is the error and it returns the Parse Error Code...
Definition: TSAXParser.cxx:172
virtual void SetParseCode(Int_t code)
Set the parse code:
Definition: TXMLParser.cxx:182
virtual ~TSAXParser()
TSAXParser desctructor.
Definition: TSAXParser.cxx:97
virtual void OnEndElement(const char *name)
Emit a signal for OnEndElement, where name is the Element's name.
Definition: TSAXParser.cxx:138
virtual void StopParser()
Stops parsing.
Definition: TXMLParser.cxx:167
#define va_(arg)
Definition: Varargs.h:41
void Error(const char *location, const char *msgfmt,...)
void Emit(const char *signal)
Acitvate signal without args.
Definition: TQObject.cxx:559
A doubly linked list.
Definition: TList.h:47
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:1135
virtual Int_t Parse()
This function parses the xml file, by initializing the parser and checks whether the parse context is...
Definition: TSAXParser.cxx:206
virtual void OnEndDocument()
Emit a signal for OnEndDocument.
Definition: TSAXParser.cxx:115
TClass * IsA() const
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
TXMLAttribute is the attribute of an Element.
Definition: TXMLAttr.h:20
void Warning(const char *location, const char *msgfmt,...)
virtual void OnCdataBlock(const char *text, Int_t len)
Emit a signal for OnCdataBlock.
Definition: TSAXParser.cxx:191
long Long_t
Definition: RtypesCore.h:50
TText * text
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2881
ClassImp(TSAXParser) TSAXParser
Create SAX parser.
Definition: TSAXParser.cxx:62
virtual void ConnectToHandler(const char *handlerName, void *handler)
A default TSAXParser to a user-defined Handler connection function.
Definition: TSAXParser.cxx:441
virtual void OnCharacters(const char *characters)
Emit a signal for OnCharacters, where characters are the characters outside of tags.
Definition: TSAXParser.cxx:147
virtual void Add(TObject *obj)
Definition: TList.h:81
virtual Int_t OnFatalError(const char *text)
Emit a signal for OnFactalError, where text is the error and it returns the Parse Error Code...
Definition: TSAXParser.cxx:182
virtual void OnStartElement(const char *name, const TList *attr)
Emit a signal for OnStarElement, where name is the Element's name and attribute is a TList of (TObjSt...
Definition: TSAXParser.cxx:126
virtual Int_t ParseFile(const char *filename)
It creates the parse context of the xml file, where the xml file name is filename.
Definition: TSAXParser.cxx:236