Logo ROOT   6.10/09
Reference Guide
TXMLEngine.cxx
Go to the documentation of this file.
1 // @(#)root/xml:$Id: 1bd040ac1c03c58bcad15b5206d602680a831c0a $
2 // Author: Sergey Linev 10.05.2004
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, 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 //
14 // TXMLEngine class is used to write and read ROOT XML files - TXMLFile.
15 // It does not conform to complete xml standard and cannot be used
16 // as parser for arbitrary XML files. For such cases TXMLParser should
17 // be used. This class was introduced to exclude dependency from
18 // external libraries (like libxml2) and improve speed / memory consumption.
19 //
20 //________________________________________________________________________
21 
22 #include "TXMLEngine.h"
23 
24 #include "Riostream.h"
25 #include "TString.h"
26 #include "TNamed.h"
27 #include "TObjArray.h"
28 #include <stdlib.h>
29 #include <string.h>
30 
32 
33 struct SXmlAttr_t {
34  SXmlAttr_t *fNext;
35  // after structure itself memory for attribute name is preserved
36  // if first byte is 0, this is special attribute
37  static inline char* Name(void* arg) { return (char*)arg + sizeof(SXmlAttr_t); }
38 };
39 
41  kXML_NODE = 1, // normal node with children
42  kXML_COMMENT = 2, // comment (stored as value of node fName)
43  kXML_PI_NODE = 3, // processing instructions node (like <?name attr="" ?>
44  kXML_RAWLINE = 4, // just one line of xml code
45  kXML_CONTENT = 5 // node content, can appear many times in between of normal nodes
46 };
47 
48 struct SXmlNode_t {
49  EXmlNodeType fType; // this is node type - node, comment, processing instruction and so on
50  SXmlAttr_t *fAttr; // first attribute
51  SXmlAttr_t *fNs; // name space definition (if any)
52  SXmlNode_t *fNext; // next node on the same level of hierarchy
53  SXmlNode_t *fChild; // first child node
54  SXmlNode_t *fLastChild; // last child node
55  SXmlNode_t *fParent; // parent node
56  // consequent bytes after structure are node name
57  // if first byte is 0, next is node content
58  static inline char* Name(void* arg) { return (char*)arg + sizeof(SXmlNode_t); }
59 };
60 
61 struct SXmlDoc_t {
62  SXmlNode_t *fRootNode;
63  char *fDtdName;
64  char *fDtdRoot;
65 };
66 
67 class TXMLOutputStream {
68 protected:
69 
70  std::ostream *fOut;
71  TString *fOutStr;
72  char *fBuf;
73  char *fCurrent;
74  char *fMaxAddr;
75  char *fLimitAddr;
76 
77 public:
78  TXMLOutputStream(const char* filename, Int_t bufsize = 20000)
79  {
80  fOut = new std::ofstream(filename);
81  fOutStr = 0;
82  Init(bufsize);
83  }
84 
85  TXMLOutputStream(TString* outstr, Int_t bufsize = 20000)
86  {
87  fOut = 0;
88  fOutStr = outstr;
89  Init(bufsize);
90  }
91 
92  void Init(Int_t bufsize)
93  {
94  fBuf = (char*) malloc(bufsize);
95  fCurrent = fBuf;
96  fMaxAddr = fBuf + bufsize;
97  fLimitAddr = fBuf + int(bufsize*0.75);
98  }
99 
100  virtual ~TXMLOutputStream()
101  {
102  if (fCurrent!=fBuf) OutputCurrent();
103  delete fOut;
104  free(fBuf);
105  }
106 
107  void OutputCurrent()
108  {
109  if (fCurrent!=fBuf) {
110  if (fOut!=0)
111  fOut->write(fBuf, fCurrent-fBuf);
112  else if (fOutStr!=0)
113  fOutStr->Append(fBuf, fCurrent-fBuf);
114  }
115  fCurrent = fBuf;
116  }
117 
118  void OutputChar(char symb)
119  {
120  if (fOut!=0) fOut->put(symb); else
121  if (fOutStr!=0) fOutStr->Append(symb);
122  }
123 
124  void Write(const char* str)
125  {
126  int len = strlen(str);
127  if (fCurrent+len>=fMaxAddr) {
128  OutputCurrent();
129  fOut->write(str,len);
130  } else {
131  while (*str)
132  *fCurrent++ = *str++;
133  if (fCurrent>fLimitAddr)
134  OutputCurrent();
135  }
136  }
137 
138  void Put(char symb, Int_t cnt=1)
139  {
140  if (fCurrent+cnt>=fMaxAddr)
141  OutputCurrent();
142  if (fCurrent+cnt>=fMaxAddr)
143  for(int n=0;n<cnt;n++)
144  OutputChar(symb);
145  else {
146  for(int n=0;n<cnt;n++)
147  *fCurrent++ = symb;
148  if (fCurrent>fLimitAddr)
149  OutputCurrent();
150  }
151  }
152 };
153 
154 class TXMLEntity : public TNamed {
155  Bool_t fSystem; //! is system (file)
156 public:
157  TXMLEntity() : TNamed(), fSystem(kFALSE) {}
158  TXMLEntity(const TString& name, const TString& value, Bool_t sys) : TNamed(name, value), fSystem(sys) {}
159  Bool_t IsSystem() const { return fSystem; }
160 };
161 
162 
163 class TXMLInputStream {
164 protected:
165 
166  std::istream *fInp;
167  const char *fInpStr;
168  Int_t fInpStrLen;
169 
170  char *fBuf;
171  Int_t fBufSize;
172 
173  char *fMaxAddr;
174  char *fLimitAddr;
175 
176  Int_t fTotalPos;
177  Int_t fCurrentLine;
178 
179  TObjArray fEntities; //! array of TXMLEntity
180 
181 public:
182 
183  char *fCurrent;
184 
185  TXMLInputStream(Bool_t isfilename, const char* filename, Int_t ibufsize) :
186  fInp(0),
187  fInpStr(0),
188  fInpStrLen(0),
189  fBuf(0),
190  fBufSize(0),
191  fMaxAddr(0),
192  fLimitAddr(0),
193  fTotalPos(0),
194  fCurrentLine(0),
195  fEntities(),
196  fCurrent(0)
197  {
198  if (isfilename) {
199  fInp = new std::ifstream(filename);
200  fInpStr = 0;
201  fInpStrLen = 0;
202  } else {
203  fInp = 0;
204  fInpStr = filename;
205  fInpStrLen = filename==0 ? 0 : strlen(filename);
206  }
207 
208  fBufSize = ibufsize;
209  fBuf = (char*) malloc(fBufSize);
210 
211  fCurrent = 0;
212  fMaxAddr = 0;
213 
214  int len = DoRead(fBuf, fBufSize);
215  fCurrent = fBuf;
216  fMaxAddr = fBuf+len;
217  fLimitAddr = fBuf + int(len*0.75);
218 
219  fTotalPos = 0;
220  fCurrentLine = 1;
221 
222  fEntities.SetOwner(kTRUE);
223  }
224 
225  virtual ~TXMLInputStream()
226  {
227  delete fInp; fInp = 0;
228  free(fBuf); fBuf = 0;
229  }
230 
231  inline Bool_t EndOfFile() { return (fInp!=0) ? fInp->eof() : (fInpStrLen<=0); }
232 
233  inline Bool_t EndOfStream() { return EndOfFile() && (fCurrent>=fMaxAddr); }
234 
235  void AddEntity(TXMLEntity* ent) { fEntities.Add(ent); }
236 
237  Int_t NumEntities() const { return fEntities.GetLast() + 1; }
238 
239  TXMLEntity* FindEntity(const char* beg, Int_t len)
240  {
241  if (len<=0) return 0;
242  for (Int_t n=0; n<=fEntities.GetLast(); n++) {
243  TXMLEntity* entity = (TXMLEntity*) fEntities[n];
244  if ((Int_t) strlen(entity->GetName()) != len) continue;
245  if (strncmp(beg, entity->GetName(), len)==0) return entity;
246  }
247  return 0;
248  }
249 
250 
251  int DoRead(char* buf, int maxsize)
252  {
253  if (EndOfFile()) return 0;
254  if (fInp!=0) {
255  fInp->get(buf, maxsize, 0);
256  maxsize = strlen(buf);
257  } else {
258  if (maxsize>fInpStrLen) maxsize = fInpStrLen;
259  strncpy(buf, fInpStr, maxsize);
260  fInpStr+=maxsize;
261  fInpStrLen-=maxsize;
262  }
263  return maxsize;
264  }
265 
266  Bool_t ExpandStream()
267  {
268  if (EndOfFile()) return kFALSE;
269  fBufSize*=2;
270  int curlength = fMaxAddr - fBuf;
271  char* newbuf = (char*) realloc(fBuf, fBufSize);
272  if (newbuf==0) return kFALSE;
273 
274  fMaxAddr = newbuf + (fMaxAddr - fBuf);
275  fCurrent = newbuf + (fCurrent - fBuf);
276  fLimitAddr = newbuf + (fLimitAddr - fBuf);
277  fBuf = newbuf;
278 
279  int len = DoRead(fMaxAddr, fBufSize-curlength);
280  if (len==0) return kFALSE;
281  fMaxAddr += len;
282  fLimitAddr += int(len*0.75);
283  return kTRUE;
284  }
285 
286  Bool_t ShiftStream()
287  {
288  if (fCurrent<fLimitAddr) return kTRUE; // everything ok, can continue
289  if (EndOfFile()) return kTRUE;
290  int rest_len = fMaxAddr - fCurrent;
291  memmove(fBuf, fCurrent, rest_len);
292  int read_len = DoRead(fBuf + rest_len, fBufSize - rest_len);
293 
294  fCurrent = fBuf;
295  fMaxAddr = fBuf + rest_len + read_len;
296  fLimitAddr = fBuf + int((rest_len + read_len)*0.75);
297  return kTRUE;
298  }
299 
300  Int_t TotalPos() { return fTotalPos; }
301 
302  Int_t CurrentLine() { return fCurrentLine; }
303 
304  Bool_t ShiftCurrent(Int_t sz = 1)
305  {
306  for(int n=0;n<sz;n++) {
307  if (*fCurrent==10) fCurrentLine++;
308  if (fCurrent>=fLimitAddr) {
309  ShiftStream();
310  if (fCurrent>=fMaxAddr) return kFALSE;
311  }
312  fCurrent++;
313  }
314  fTotalPos+=sz;
315  return kTRUE;
316  }
317 
318  Bool_t SkipSpaces(Bool_t tillendl = kFALSE)
319  {
320  while (fCurrent<fMaxAddr) {
321  char symb = *fCurrent;
322  if ((symb>26) && (symb!=' ')) return kTRUE;
323 
324  if (!ShiftCurrent()) return kFALSE;
325 
326  if (tillendl && (symb==10)) return kTRUE;
327  }
328  return kFALSE;
329  }
330 
331  Bool_t CheckFor(const char* str)
332  {
333  // Check if in current position we see specified string
334  int len = strlen(str);
335  while (fCurrent+len>fMaxAddr)
336  if (!ExpandStream()) return kFALSE;
337  char* curr = fCurrent;
338  while (*str != 0)
339  if (*str++ != *curr++) return kFALSE;
340  return ShiftCurrent(len);
341  }
342 
343  Int_t SearchFor(const char* str)
344  {
345  // Serach for specified string in the stream
346  // return number of symbols before string was found, -1 if error
347  int len = strlen(str);
348 
349  char* curr = fCurrent;
350 
351  do {
352  curr++;
353  while (curr+len>fMaxAddr)
354  if (!ExpandStream()) return -1;
355  char* chk0 = curr;
356  const char* chk = str;
357  Bool_t find = kTRUE;
358  while (*chk != 0)
359  if (*chk++ != *chk0++) { find = kFALSE; break; }
360  // if string found, shift to the next symbol after string
361  if (find) return curr - fCurrent;
362  } while (curr<fMaxAddr);
363  return -1;
364  }
365 
366 #define GoodStartSymbol(symb) \
367  (((symb>='a') && (symb<='z')) || ((symb>='A') && (symb<='Z')) || (symb=='_') || \
368  ((symb>=0xc0) && (symb<=0xd6)) || ((symb>=0xd8) && (symb<=0xf6)) || (symb>0xf8))
369 
370  Int_t LocateIdentifier()
371  {
372  unsigned char symb = (unsigned char) *fCurrent;
373 
374  Bool_t ok = GoodStartSymbol(symb);
375  if (!ok) return 0;
376 
377  char* curr = fCurrent;
378 
379  do {
380  curr++;
381  if (curr>=fMaxAddr)
382  if (!ExpandStream()) return 0;
383  symb = (unsigned char) *curr;
384  ok = GoodStartSymbol(symb) ||
385  ((symb>='0') && (symb<='9')) || (symb==':') || (symb=='-') || (symb=='.') || (symb==0xb7);
386  if (!ok) return curr-fCurrent;
387  } while (curr<fMaxAddr);
388  return 0;
389  }
390 
391  Int_t LocateContent()
392  {
393  char* curr = fCurrent;
394  while (curr<fMaxAddr) {
395  char symb = *curr;
396  if (symb=='<') return curr - fCurrent;
397  curr++;
398  if (curr>=fMaxAddr)
399  if (!ExpandStream()) return -1;
400  }
401  return -1;
402  }
403 
404  Int_t LocateValue(char* start, bool withequalsign = true)
405  {
406  char* curr = start;
407  if (curr>=fMaxAddr)
408  if (!ExpandStream()) return 0;
409  if (withequalsign) {
410  if (*curr!='=') return 0;
411  curr++;
412  if (curr>=fMaxAddr)
413  if (!ExpandStream()) return 0;
414  }
415  if ((*curr!='\"') && (*curr!='\'')) return 0;
416  char quote = *curr;
417  do {
418  curr++;
419  if (curr>=fMaxAddr)
420  if (!ExpandStream()) return 0;
421  if (*curr==quote) return curr-start+1;
422  } while (curr<fMaxAddr);
423  return 0;
424  }
425 };
426 
427 ////////////////////////////////////////////////////////////////////////////////
428 /// default (normal) constructor of TXMLEngine class
429 
431 {
432  fSkipComments = kFALSE;
433 }
434 
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// destructor for TXMLEngine object
438 
440 {
441 }
442 
443 ////////////////////////////////////////////////////////////////////////////////
444 /// checks if node has attribute of specified name
445 
447 {
448  if ((xmlnode==0) || (name==0)) return kFALSE;
449  SXmlAttr_t* attr = ((SXmlNode_t*)xmlnode)->fAttr;
450  while (attr!=0) {
451  if (strcmp(SXmlAttr_t::Name(attr),name)==0) return kTRUE;
452  attr = attr->fNext;
453  }
454  return kFALSE;
455 }
456 
457 ////////////////////////////////////////////////////////////////////////////////
458 /// returns value of attribute for xmlnode
459 
460 const char* TXMLEngine::GetAttr(XMLNodePointer_t xmlnode, const char* name)
461 {
462  if (xmlnode==0) return 0;
463  SXmlAttr_t* attr = ((SXmlNode_t*)xmlnode)->fAttr;
464  while (attr!=0) {
465  if (strcmp(SXmlAttr_t::Name(attr),name)==0)
466  return SXmlAttr_t::Name(attr) + strlen(name) + 1;
467  attr = attr->fNext;
468  }
469  return 0;
470 }
471 
472 ////////////////////////////////////////////////////////////////////////////////
473 /// returns value of attribute as integer
474 
476 {
477  if (xmlnode==0) return 0;
478  Int_t res = 0;
479  const char* attr = GetAttr(xmlnode, name);
480  if (attr) sscanf(attr, "%d", &res);
481  return res;
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// creates new attribute for xmlnode,
486 /// namespaces are not supported for attributes
487 
489  const char* name, const char* value)
490 {
491  if (xmlnode==0) return 0;
492 
493  int namelen(name != 0 ? strlen(name) : 0);
494  int valuelen(value != 0 ? strlen(value) : 0);
495  SXmlAttr_t* attr = (SXmlAttr_t*) AllocateAttr(namelen, valuelen, xmlnode);
496 
497  char* attrname = SXmlAttr_t::Name(attr);
498  if (namelen>0)
499  strncpy(attrname, name, namelen+1);
500  else
501  *attrname = 0;
502  attrname += (namelen + 1);
503  if (valuelen>0)
504  strncpy(attrname, value, valuelen+1);
505  else
506  *attrname = 0;
507 
508  return (XMLAttrPointer_t) attr;
509 }
510 
511 ////////////////////////////////////////////////////////////////////////////////
512 /// create node attribute with integer value
513 
515  const char* name,
516  Int_t value)
517 {
518  char sbuf[30];
519  sprintf(sbuf,"%d",value);
520  return NewAttr(xmlnode, 0, name, sbuf);
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// remove attribute from xmlnode
525 
526 void TXMLEngine::FreeAttr(XMLNodePointer_t xmlnode, const char* name)
527 {
528  if (xmlnode==0) return;
529  SXmlAttr_t* attr = ((SXmlNode_t*) xmlnode)->fAttr;
530  SXmlAttr_t* prev = 0;
531  while (attr!=0) {
532  if (strcmp(SXmlAttr_t::Name(attr),name)==0) {
533  if (prev!=0)
534  prev->fNext = attr->fNext;
535  else
536  ((SXmlNode_t*) xmlnode)->fAttr = attr->fNext;
537  //fNumNodes--;
538  free(attr);
539  return;
540  }
541 
542  prev = attr;
543  attr = attr->fNext;
544  }
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Free all attributes of the node
549 
551 {
552  if (xmlnode==0) return;
553 
554  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
555  SXmlAttr_t* attr = node->fAttr;
556  while (attr!=0) {
557  SXmlAttr_t* next = attr->fNext;
558  free(attr);
559  attr = next;
560  }
561  node->fAttr = 0;
562 }
563 
564 
565 ////////////////////////////////////////////////////////////////////////////////
566 /// return first attribute in the list, namespace (if exists) will be skiped
567 
569 {
570  if (xmlnode==0) return 0;
571  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
572 
573  SXmlAttr_t* attr = node->fAttr;
574  if ((attr!=0) && (node->fNs==attr)) attr = attr->fNext;
575 
576  return (XMLAttrPointer_t) attr;
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// return next attribute in the list
581 
583 {
584  if (xmlattr==0) return 0;
585 
586  return (XMLAttrPointer_t) ((SXmlAttr_t*) xmlattr)->fNext;
587 }
588 
589 ////////////////////////////////////////////////////////////////////////////////
590 /// return name of the attribute
591 
593 {
594  if (xmlattr==0) return 0;
595 
596  return SXmlAttr_t::Name(xmlattr);
597 
598 }
599 
600 ////////////////////////////////////////////////////////////////////////////////
601 /// return value of attribute
602 
604 {
605  if (xmlattr==0) return 0;
606 
607  const char* attrname = SXmlAttr_t::Name(xmlattr);
608  return attrname + strlen(attrname) + 1;
609 }
610 
611 ////////////////////////////////////////////////////////////////////////////////
612 /// create new child element for parent node
613 
615  const char* name, const char* content)
616 {
617  int namelen(name!=0 ? strlen(name) : 0);
618 
619  SXmlNode_t* node = (SXmlNode_t*) AllocateNode(namelen, parent);
620 
621  if (namelen>0)
622  strncpy(SXmlNode_t::Name(node), name, namelen+1);
623  else
624  *SXmlNode_t::Name(node) = 0;
625 
626  node->fNs = (SXmlAttr_t*) ns;
627  int contlen = (content!=0) ? strlen(content) : 0;
628  if (contlen>0) {
629  SXmlNode_t* contnode = (SXmlNode_t*) AllocateNode(contlen, node);
630  contnode->fType = kXML_CONTENT; // indicate that we creating content node
631  strncpy(SXmlNode_t::Name(contnode), content, contlen+1);
632  }
633 
634  return (XMLNodePointer_t) node;
635 }
636 
637 ////////////////////////////////////////////////////////////////////////////////
638 /// create namespace attribute for xmlnode.
639 /// namespace attribute will be always the first in list of node attributes
640 
641 XMLNsPointer_t TXMLEngine::NewNS(XMLNodePointer_t xmlnode, const char* reference, const char* name)
642 {
643  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
644  if (name==0) name = SXmlNode_t::Name(node);
645  int namelen = strlen(name);
646  char* nsname = new char[namelen+7];
647  snprintf(nsname, namelen+7, "xmlns:%s", name);
648 
649  SXmlAttr_t* first = node->fAttr;
650  node->fAttr = 0;
651 
652  SXmlAttr_t* nsattr = (SXmlAttr_t*) NewAttr(xmlnode, 0, nsname, reference);
653 
654  node->fAttr = nsattr;
655  nsattr->fNext = first;
656 
657  node->fNs = nsattr;
658  delete[] nsname;
659  return (XMLNsPointer_t) nsattr;
660 }
661 
662 ////////////////////////////////////////////////////////////////////////////////
663 /// return namespace attribute (if exists)
664 
666 {
667  if (xmlnode==0) return 0;
668  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
669 
670  return (XMLNsPointer_t) node->fNs;
671 }
672 
673 ////////////////////////////////////////////////////////////////////////////////
674 /// return name id of namespace
675 
677 {
678  const char* nsname = GetAttrName((XMLAttrPointer_t)ns);
679 
680  if ((nsname!=0) && (strncmp(nsname,"xmlns:",6)==0)) nsname+=6;
681 
682  return nsname;
683 }
684 
685 ////////////////////////////////////////////////////////////////////////////////
686 /// return reference id of namespace
687 
689 {
690  return GetAttrValue((XMLAttrPointer_t)ns);
691 }
692 
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 /// add child element to xmlnode
696 
698 {
699  if ((parent==0) || (child==0)) return;
700  SXmlNode_t* pnode = (SXmlNode_t*) parent;
701  SXmlNode_t* cnode = (SXmlNode_t*) child;
702  cnode->fParent = pnode;
703  if (pnode->fLastChild==0) {
704  pnode->fChild = cnode;
705  pnode->fLastChild = cnode;
706  } else {
707  //SXmlNode_t* ch = pnode->fChild;
708  //while (ch->fNext!=0) ch=ch->fNext;
709  pnode->fLastChild->fNext = cnode;
710  pnode->fLastChild = cnode;
711  }
712 }
713 
714 ////////////////////////////////////////////////////////////////////////////////
715 /// add node as first child
716 
718 {
719  if ((parent==0) || (child==0)) return;
720  SXmlNode_t* pnode = (SXmlNode_t*) parent;
721  SXmlNode_t* cnode = (SXmlNode_t*) child;
722  cnode->fParent = pnode;
723 
724  cnode->fNext = pnode->fChild;
725  pnode->fChild = cnode;
726 
727  if (pnode->fLastChild==0) pnode->fLastChild = cnode;
728 }
729 
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 /// Adds comment line to the node
733 
734 Bool_t TXMLEngine::AddComment(XMLNodePointer_t xmlnode, const char* comment)
735 {
736  if ((xmlnode==0) || (comment==0)) return kFALSE;
737 
738  int commentlen = strlen(comment);
739 
740  SXmlNode_t* node = (SXmlNode_t*) AllocateNode(commentlen, xmlnode);
741  node->fType = kXML_COMMENT;
742  strncpy(SXmlNode_t::Name(node), comment, commentlen+1);
743 
744  return kTRUE;
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// add comment line to the top of the document
749 
751 {
752  if (xmldoc==0) return kFALSE;
753 
754  XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
755  UnlinkNode(rootnode);
756 
757  Bool_t res = AddComment(((SXmlDoc_t*)xmldoc)->fRootNode, comment);
758 
759  AddChild((XMLNodePointer_t) ((SXmlDoc_t*)xmldoc)->fRootNode, rootnode);
760 
761  return res;
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Add just line into xml file
766 /// Line should has correct xml syntax that later it can be decoded by xml parser
767 /// For instance, it can be comment or processing instructions
768 
770 {
771  if ((xmlnode==0) || (line==0)) return kFALSE;
772 
773  int linelen = strlen(line);
774  SXmlNode_t* node = (SXmlNode_t*) AllocateNode(linelen, xmlnode);
775  node->fType = kXML_RAWLINE;
776  strncpy(SXmlNode_t::Name(node), line, linelen+1);
777 
778  return kTRUE;
779 }
780 
781 ////////////////////////////////////////////////////////////////////////////////
782 /// Add just line on the top of xml document
783 /// Line should has correct xml syntax that later it can be decoded by xml parser
784 
786 {
787  XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
788  UnlinkNode(rootnode);
789 
790  Bool_t res = AddRawLine(((SXmlDoc_t*)xmldoc)->fRootNode, line);
791 
792  AddChild((XMLNodePointer_t) ((SXmlDoc_t*)xmldoc)->fRootNode, rootnode);
793 
794  return res;
795 
796 }
797 
798 
799 ////////////////////////////////////////////////////////////////////////////////
800 /// Adds style sheet definition to the specified node
801 /// Creates <?xml-stylesheet alternate="yes" title="compact" href="small-base.css" type="text/css"?>
802 /// Attributes href and type must be supplied,
803 /// other attributes: title, alternate, media, charset are optional
804 /// if alternate==0, attribyte alternate="no" will be created,
805 /// if alternate>0, attribute alternate="yes"
806 /// if alternate<0, attribute will not be created
807 
809  const char* href,
810  const char* type,
811  const char* title,
812  int alternate,
813  const char* media,
814  const char* charset)
815 {
816  if ((xmlnode==0) || (href==0) || (type==0)) return kFALSE;
817 
818  const char* nodename = "xml-stylesheet";
819  int nodenamelen = strlen(nodename);
820 
821  SXmlNode_t* node = (SXmlNode_t*) AllocateNode(nodenamelen, xmlnode);
822  node->fType = kXML_PI_NODE;
823  strncpy(SXmlNode_t::Name(node), nodename, nodenamelen+1);
824 
825  if (alternate>=0)
826  NewAttr(node, 0, "alternate", (alternate>0) ? "yes" : "no");
827 
828  if (title!=0) NewAttr(node, 0, "title", title);
829 
830  NewAttr(node, 0, "href", href);
831  NewAttr(node, 0, "type", type);
832 
833  if (media!=0) NewAttr(node, 0, "media", media);
834  if (charset!=0) NewAttr(node, 0, "charset", charset);
835 
836  return kTRUE;
837 }
838 
839 
840 ////////////////////////////////////////////////////////////////////////////////
841 /// Add style sheet definition on the top of document
842 
844  const char* href,
845  const char* type,
846  const char* title,
847  int alternate,
848  const char* media,
849  const char* charset)
850 {
851  if (xmldoc==0) return kFALSE;
852 
853  XMLNodePointer_t rootnode = DocGetRootElement(xmldoc);
854  UnlinkNode(rootnode);
855 
856  Bool_t res = AddStyleSheet(((SXmlDoc_t*)xmldoc)->fRootNode,
857  href,type,title,alternate,media,charset);
858 
859  AddChild((XMLNodePointer_t) ((SXmlDoc_t*)xmldoc)->fRootNode, rootnode);
860 
861  return res;
862 }
863 
864 ////////////////////////////////////////////////////////////////////////////////
865 /// unlink (dettach) xml node from parent
866 
868 {
869  if (xmlnode==0) return;
870  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
871 
872  SXmlNode_t* parent = node->fParent;
873 
874  if (parent==0) return;
875 
876  if (parent->fChild==node) {
877  parent->fChild = node->fNext;
878  if (parent->fLastChild==node)
879  parent->fLastChild = node->fNext;
880  } else {
881  SXmlNode_t* ch = parent->fChild;
882  while (ch->fNext!=node) ch = ch->fNext;
883  ch->fNext = node->fNext;
884  if (parent->fLastChild == node)
885  parent->fLastChild = ch;
886  }
887 }
888 
889 ////////////////////////////////////////////////////////////////////////////////
890 /// release all memory, allocated fro this node and
891 /// destroyes node itself
892 
894 {
895  if (xmlnode==0) return;
896  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
897 
898  SXmlNode_t* child = node->fChild;
899  while (child!=0) {
900  SXmlNode_t* next = child->fNext;
901  FreeNode((XMLNodePointer_t)child);
902  child = next;
903  }
904 
905  SXmlAttr_t* attr = node->fAttr;
906  while (attr!=0) {
907  SXmlAttr_t* next = attr->fNext;
908  //fNumNodes--;
909  free(attr);
910  attr = next;
911  }
912 
913  free(node);
914 
915  //fNumNodes--;
916 }
917 
918 ////////////////////////////////////////////////////////////////////////////////
919 /// combined operation. Unlink node and free used memory
920 
922 {
923  UnlinkNode(xmlnode);
924  FreeNode(xmlnode);
925 }
926 
927 ////////////////////////////////////////////////////////////////////////////////
928 /// returns name of xmlnode
929 
931 {
932  return xmlnode==0 ? 0 : SXmlNode_t::Name(xmlnode);
933 }
934 
935 ////////////////////////////////////////////////////////////////////////////////
936 /// get contents (if any) of xml node
937 
939 {
940  if (xmlnode==0) return 0;
941  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
942  if (node->fChild == 0) return 0;
943 
944  if (node->fChild->fType != kXML_CONTENT) return 0;
945 
946  return SXmlNode_t::Name(node->fChild);
947 }
948 
949 ////////////////////////////////////////////////////////////////////////////////
950 /// set content of the xml node
951 /// if old node content was exists, it will be replaced
952 
953 void TXMLEngine::SetNodeContent(XMLNodePointer_t xmlnode, const char* content, Int_t len)
954 {
955  if (xmlnode==0) return;
956  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
957  if ((node->fChild != 0) && (node->fChild->fType == kXML_CONTENT))
958  UnlinkFreeNode((XMLNodePointer_t) node->fChild);
959 
960  if (content==0) return;
961  if (len<=0) len = strlen(content);
962 
963  SXmlNode_t* contnode = (SXmlNode_t*) AllocateNode(len, 0);
964  char* nameptr = SXmlNode_t::Name(contnode);
965  contnode->fType = kXML_CONTENT;
966  strncpy(nameptr, content, len);
967  nameptr+=len;
968  *nameptr = 0; // here we add padding 0 to get normal string
969 
970  AddChildFirst(xmlnode, (XMLNodePointer_t)contnode);
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// add new content of the xml node
975 /// old content will be preserved, one could mix content with child nodes
976 
977 void TXMLEngine::AddNodeContent(XMLNodePointer_t xmlnode, const char* content, Int_t len)
978 {
979  if ((xmlnode==0) || (content==0)) return;
980  if (len<=0) len = strlen(content);
981 
982  SXmlNode_t* contnode = (SXmlNode_t*) AllocateNode(len, xmlnode);
983  char* nameptr = SXmlNode_t::Name(contnode);
984  contnode->fType = kXML_CONTENT;
985  strncpy(nameptr, content, len);
986  nameptr+=len;
987  *nameptr = 0; // here we add padding 0 to get normal string
988 }
989 
990 ////////////////////////////////////////////////////////////////////////////////
991 /// returns first child of xml node
992 
994 {
995  XMLNodePointer_t res = xmlnode==0 ? 0 :((SXmlNode_t*) xmlnode)->fChild;
996  // skip content(s) node, if specified
997  if (realnode && (res!=0) && (((SXmlNode_t*)res)->fType != kXML_NODE)) ShiftToNext(res, kTRUE);
998  return res;
999 }
1000 
1001 ////////////////////////////////////////////////////////////////////////////////
1002 /// returns parent of xmlnode
1003 
1005 {
1006  return xmlnode==0 ? 0 : (XMLNodePointer_t) ((SXmlNode_t*) xmlnode)->fParent;
1007 }
1008 
1009 ////////////////////////////////////////////////////////////////////////////////
1010 /// return next to xmlnode node
1011 /// if realnode==kTRUE, any special nodes in between will be skipped
1012 
1014 {
1015  do {
1016  xmlnode = xmlnode==0 ? 0 : (XMLNodePointer_t) ((SXmlNode_t*) xmlnode)->fNext;
1017  if ((xmlnode==0) || !realnode) return xmlnode;
1018  } while (((SXmlNode_t*) xmlnode)->fType != kXML_NODE);
1019 
1020  return xmlnode;
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////////////////
1024 /// shifts specified node to next
1025 /// if realnode==kTRUE, any special nodes in between will be skipped
1026 
1028 {
1029  do {
1030  xmlnode = xmlnode==0 ? 0 : (XMLNodePointer_t) ((SXmlNode_t*) xmlnode)->fNext;
1031  if ((xmlnode==0) || !realnode) return;
1032  } while (((SXmlNode_t*) xmlnode)->fType != kXML_NODE);
1033 }
1034 
1035 ////////////////////////////////////////////////////////////////////////////////
1036 /// return kTRUE is this is normal xml node
1037 
1039 {
1040  return xmlnode==0 ? kFALSE : (((SXmlNode_t*) xmlnode)->fType == kXML_NODE);
1041 }
1042 
1043 ////////////////////////////////////////////////////////////////////////////////
1044 /// return kTRUE is this is node with special data like comments to data processing instructions
1045 
1047 {
1048  return xmlnode==0 ? kTRUE : (((SXmlNode_t*) xmlnode)->fType != kXML_NODE);
1049 }
1050 
1051 ////////////////////////////////////////////////////////////////////////////////
1052 /// return kTRUE is this is special node with content
1053 
1055 {
1056  return xmlnode==0 ? kFALSE : (((SXmlNode_t*) xmlnode)->fType == kXML_CONTENT);
1057 }
1058 
1059 ////////////////////////////////////////////////////////////////////////////////
1060 /// return kTRUE is this is special node with content
1061 
1063 {
1064  return xmlnode==0 ? kFALSE : (((SXmlNode_t*) xmlnode)->fType == kXML_COMMENT);
1065 }
1066 
1067 
1068 ////////////////////////////////////////////////////////////////////////////////
1069 /// Skip all current empty nodes and locate on first "true" node
1070 
1072 {
1073  if (IsEmptyNode(xmlnode)) ShiftToNext(xmlnode);
1074 }
1075 
1076 
1077 ////////////////////////////////////////////////////////////////////////////////
1078 /// remove all children node from xmlnode
1079 
1081 {
1082  if (xmlnode==0) return;
1083  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
1084 
1085  SXmlNode_t* child = node->fChild;
1086  while (child!=0) {
1087  SXmlNode_t* next = child->fNext;
1088  FreeNode((XMLNodePointer_t)child);
1089  child = next;
1090  }
1091 
1092  node->fChild = 0;
1093  node->fLastChild = 0;
1094 }
1095 
1096 ////////////////////////////////////////////////////////////////////////////////
1097 /// creates new xml document with provided version
1098 
1100 {
1101  SXmlDoc_t* doc = new SXmlDoc_t;
1102  doc->fRootNode = (SXmlNode_t*) NewChild(0, 0, "??DummyTopNode??", 0);
1103 
1104  if (version!=0) {
1105  XMLNodePointer_t vernode = NewChild( (XMLNodePointer_t) doc->fRootNode, 0, "xml");
1106  ((SXmlNode_t*) vernode)->fType = kXML_PI_NODE;
1107  NewAttr(vernode, 0, "version", version);
1108  }
1109 
1110  doc->fDtdName = 0;
1111  doc->fDtdRoot = 0;
1112  return (XMLDocPointer_t) doc;
1113 }
1114 
1115 ////////////////////////////////////////////////////////////////////////////////
1116 /// assignes dtd filename to document
1117 
1118 void TXMLEngine::AssignDtd(XMLDocPointer_t xmldoc, const char* dtdname, const char* rootname)
1119 {
1120  if (xmldoc==0) return;
1121  SXmlDoc_t* doc = (SXmlDoc_t*) xmldoc;
1122  delete[] doc->fDtdName;
1123  doc->fDtdName = Makestr(dtdname);
1124  delete[] doc->fDtdRoot;
1125  doc->fDtdRoot = Makestr(rootname);
1126 }
1127 
1128 ////////////////////////////////////////////////////////////////////////////////
1129 /// frees allocated document data and deletes document itself
1130 
1132 {
1133  if (xmldoc==0) return;
1134  SXmlDoc_t* doc = (SXmlDoc_t*) xmldoc;
1135  FreeNode((XMLNodePointer_t) doc->fRootNode);
1136  delete[] doc->fDtdName;
1137  delete[] doc->fDtdRoot;
1138  delete doc;
1139 }
1140 
1141 ////////////////////////////////////////////////////////////////////////////////
1142 /// store document content to file
1143 /// if layout<=0, no any spaces or newlines will be placed between
1144 /// xmlnodes. Xml file will have minimum size, but nonreadable structure
1145 /// if (layout>0) each node will be started from new line,
1146 /// and number of spaces will correspond to structure depth.
1147 
1148 void TXMLEngine::SaveDoc(XMLDocPointer_t xmldoc, const char* filename, Int_t layout)
1149 {
1150  if (xmldoc==0) return;
1151 
1152  SXmlDoc_t* doc = (SXmlDoc_t*) xmldoc;
1153 
1154  TXMLOutputStream out(filename, 100000);
1155 
1156  XMLNodePointer_t child = GetChild((XMLNodePointer_t) doc->fRootNode, kFALSE);
1157 
1158  do {
1159  SaveNode(child, &out, layout, 0);
1160  ShiftToNext(child, kFALSE);
1161  } while (child!=0);
1162 
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 /// set main (root) node for document
1167 
1169 {
1170  if (xmldoc==0) return;
1171 
1172  FreeNode(DocGetRootElement(xmldoc));
1173 
1174  AddChild((XMLNodePointer_t) ((SXmlDoc_t*)xmldoc)->fRootNode, xmlnode);
1175 }
1176 
1177 ////////////////////////////////////////////////////////////////////////////////
1178 /// returns root node of document
1179 
1181 {
1182  if (xmldoc==0) return 0;
1183 
1184  XMLNodePointer_t xmlnode = (XMLNodePointer_t) ((SXmlDoc_t*)xmldoc)->fRootNode;
1185 
1186  // typically first child of XML document is version
1187  // therefore just skip it when returning root node of document
1188  return GetChild(xmlnode, kTRUE);
1189 }
1190 
1191 ////////////////////////////////////////////////////////////////////////////////
1192 /// Parses content of file and tries to produce xml structures.
1193 /// The maxbuf argument specifies the max size of the XML file to be
1194 /// parsed. The default value is 100000.
1195 
1196 XMLDocPointer_t TXMLEngine::ParseFile(const char* filename, Int_t maxbuf)
1197 {
1198  if ((filename==0) || (strlen(filename)==0)) return 0;
1199  if (maxbuf < 100000) maxbuf = 100000;
1200  TXMLInputStream inp(true, filename, maxbuf);
1201  return ParseStream(&inp);
1202 }
1203 
1204 ////////////////////////////////////////////////////////////////////////////////
1205 /// parses content of string and tries to produce xml structures
1206 
1208 {
1209  if ((xmlstring==0) || (strlen(xmlstring)==0)) return 0;
1210  TXMLInputStream inp(false, xmlstring, 2*strlen(xmlstring) );
1211  return ParseStream(&inp);
1212 }
1213 
1214 ////////////////////////////////////////////////////////////////////////////////
1215 /// parses content of the stream and tries to produce xml structures
1216 
1218 {
1219  if (inp == 0) return 0;
1220 
1221  XMLDocPointer_t xmldoc = NewDoc(0);
1222 
1223  Bool_t success = false;
1224 
1225  Int_t resvalue = 0;
1226 
1227  do {
1228  ReadNode(((SXmlDoc_t*) xmldoc)->fRootNode, inp, resvalue);
1229 
1230  if (resvalue!=2) break;
1231 
1232  // coverity[unchecked_value] at this place result of SkipSpaces() doesn't matter - either file is finished (false) or there is some more nodes to analyse (true)
1233  if (!inp->EndOfStream()) inp->SkipSpaces();
1234 
1235  if (inp->EndOfStream()) {
1236  success = true;
1237  break;
1238  }
1239  } while (true);
1240 
1241  if (!success) {
1242  DisplayError(resvalue, inp->CurrentLine());
1243  FreeDoc(xmldoc);
1244  return 0;
1245  }
1246 
1247  return xmldoc;
1248 }
1249 
1250 ////////////////////////////////////////////////////////////////////////////////
1251 /// check that first node is xml processing instruction with correct xml version number
1252 
1254 {
1255  if (xmldoc==0) return kFALSE;
1256 
1257  XMLNodePointer_t vernode = GetChild((XMLNodePointer_t) ((SXmlDoc_t*) xmldoc)->fRootNode, kFALSE);
1258  if (vernode==0) return kFALSE;
1259 
1260  if (((SXmlNode_t*) vernode)->fType!=kXML_PI_NODE) return kFALSE;
1261  if (strcmp(GetNodeName(vernode), "xml")!=0) return kFALSE;
1262 
1263  const char* value = GetAttr(vernode,"version");
1264  if (value==0) return kFALSE;
1265  if (version==0) version = "1.0";
1266 
1267  return strcmp(version,value)==0;
1268 }
1269 
1270 ////////////////////////////////////////////////////////////////////////////////
1271 /// convert single xml node (and its child node) to string
1272 /// if layout<=0, no any spaces or newlines will be placed between
1273 /// xmlnodes. Xml file will have minimum size, but nonreadable structure
1274 /// if (layout>0) each node will be started from new line,
1275 /// and number of spaces will correspond to structure depth.
1276 
1278 {
1279  if ((res==0) || (xmlnode==0)) return;
1280 
1281  TXMLOutputStream out(res, 10000);
1282 
1283  SaveNode(xmlnode, &out, layout, 0);
1284 }
1285 
1286 ////////////////////////////////////////////////////////////////////////////////
1287 /// read single xml node from provided string
1288 
1290 {
1291  if (src==0) return 0;
1292 
1293  TXMLInputStream inp(false, src, 10000);
1294 
1295  Int_t resvalue;
1296 
1297  XMLNodePointer_t xmlnode = ReadNode(0, &inp, resvalue);
1298 
1299  if (resvalue<=0) {
1300  DisplayError(resvalue, inp.CurrentLine());
1301  FreeNode(xmlnode);
1302  return 0;
1303  }
1304 
1305  return xmlnode;
1306 }
1307 
1308 ////////////////////////////////////////////////////////////////////////////////
1309 /// creates char* variable with copy of provided string
1310 
1311 char* TXMLEngine::Makestr(const char* str)
1312 {
1313  if (str==0) return 0;
1314  int len = strlen(str);
1315  if (len==0) return 0;
1316  char* res = new char[len+1];
1317  strncpy(res, str, len+1);
1318  return res;
1319 }
1320 
1321 ////////////////////////////////////////////////////////////////////////////////
1322 /// creates char* variable with copy of len symbols from provided string
1323 
1324 char* TXMLEngine::Makenstr(const char* str, int len)
1325 {
1326  if ((str==0) || (len==0)) return 0;
1327  char* res = new char[len+1];
1328  strncpy(res, str, len);
1329  *(res+len) = 0;
1330  return res;
1331 }
1332 
1333 ////////////////////////////////////////////////////////////////////////////////
1334 /// Allocates new xml node with specified namelength
1335 
1337 {
1338  //fNumNodes++;
1339 
1340  SXmlNode_t* node = (SXmlNode_t*) malloc(sizeof(SXmlNode_t) + namelen + 1);
1341 
1342  node->fType = kXML_NODE;
1343  node->fParent = 0;
1344  node->fNs = 0;
1345  node->fAttr = 0;
1346  node->fChild = 0;
1347  node->fLastChild = 0;
1348  node->fNext = 0;
1349 
1350  if (parent!=0)
1351  AddChild(parent, (XMLNodePointer_t) node);
1352 
1353  return (XMLNodePointer_t) node;
1354 }
1355 
1356 ////////////////////////////////////////////////////////////////////////////////
1357 /// Allocate new attribute with specified name length and value length
1358 
1360 {
1361  //fNumNodes++;
1362 
1363  SXmlAttr_t* attr = (SXmlAttr_t*) malloc(sizeof(SXmlAttr_t) + namelen + 1 + valuelen + 1);
1364 
1365  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
1366 
1367  attr->fNext = 0;
1368 
1369  if (node->fAttr==0)
1370  node->fAttr = attr;
1371  else {
1372  SXmlAttr_t* d = node->fAttr;
1373  while (d->fNext!=0) d = d->fNext;
1374  d->fNext = attr;
1375  }
1376 
1377  return (XMLAttrPointer_t) attr;
1378 }
1379 
1380 ////////////////////////////////////////////////////////////////////////////////
1381 /// define if namespace of that name exists for xmlnode
1382 
1384 {
1385  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
1386  while (node!=0) {
1387  if (node->fNs!=0) {
1388  const char* nsname = SXmlAttr_t::Name(node->fNs) + 6;
1389  if (strcmp(nsname, name)==0) return node->fNs;
1390  }
1391  node = node->fParent;
1392  }
1393  return 0;
1394 }
1395 
1396 ////////////////////////////////////////////////////////////////////////////////
1397 /// removes namespace extension of nodename
1398 
1400 {
1401  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
1402  if (node==0) return;
1403  char* colon = strchr(SXmlNode_t::Name(node),':');
1404  if (colon==0) return;
1405 
1406  char* copyname = SXmlNode_t::Name(node);
1407 
1408  while (*colon!=0)
1409  *(copyname++) = *(++colon);
1410 }
1411 
1412 ////////////////////////////////////////////////////////////////////////////////
1413 /// unpack special symbols, used in xml syntax to code characters
1414 /// these symbols: '<' - &lt, '>' - &gt, '&' - &amp, '"' - &quot, ''' - &apos
1415 
1416 void TXMLEngine::UnpackSpecialCharacters(char* target, const char* source, int srclen)
1417 {
1418  while (srclen>0) {
1419  if (*source=='&') {
1420  if ((srclen>3) && (*(source+1)=='l') && (*(source+2)=='t') && (*(source+3)==';')) {
1421  *target++ = '<'; source+=4; srclen-=4;
1422  } else
1423  if ((srclen>3) && (*(source+1)=='g') && (*(source+2)=='t') && (*(source+3)==';')) {
1424  *target++ = '>'; source+=4; srclen-=4;
1425  } else
1426  if ((srclen>4) && (*(source+1)=='a') && (*(source+2)=='m') && (*(source+3)=='p') && (*(source+4)==';')) {
1427  *target++ = '&'; source+=5; srclen-=5;
1428  } else
1429  if ((srclen>5) && (*(source+1)=='q') && (*(source+2)=='u') && (*(source+3)=='o') && (*(source+4)=='t') && (*(source+5)==';')) {
1430  *target++ = '\"'; source+=6; srclen-=6;
1431  } else
1432  if ((srclen>5) && (*(source+1)=='a') && (*(source+2)=='p') && (*(source+3)=='o') && (*(source+4)=='s') && (*(source+5)==';')) {
1433  *target++ = '\''; source+=6; srclen-=6;
1434  } else {
1435  *target++ = *source++; srclen--;
1436  }
1437  } else {
1438  *target++ = *source++;
1439  srclen--;
1440  }
1441  }
1442  *target = 0;
1443 }
1444 
1445 ////////////////////////////////////////////////////////////////////////////////
1446 /// output value to output stream
1447 /// if symbols '<' '&' '>' '"' ''' appears in the string, they
1448 /// will be encoded to appropriate xml symbols: &lt, &amp, &gt, &quot, &apos
1449 
1450 void TXMLEngine::OutputValue(char* value, TXMLOutputStream* out)
1451 {
1452  if (value==0) return;
1453 
1454  char* last = value;
1455  char* find = 0;
1456  while ((find=strpbrk(last,"<&>\"")) !=0 ) {
1457  char symb = *find;
1458  *find = 0;
1459  out->Write(last);
1460  *find = symb;
1461  last = find+1;
1462  if (symb=='<') out->Write("&lt;");
1463  else if (symb=='>') out->Write("&gt;");
1464  else if (symb=='&') out->Write("&amp;");
1465  else if (symb=='\'') out->Write("&apos;");
1466  else out->Write("&quot;");
1467  }
1468  if (*last!=0)
1469  out->Write(last);
1470 }
1471 
1472 ////////////////////////////////////////////////////////////////////////////////
1473 /// stream data of xmlnode to output
1474 
1475 void TXMLEngine::SaveNode(XMLNodePointer_t xmlnode, TXMLOutputStream* out, Int_t layout, Int_t level)
1476 {
1477  if (xmlnode==0) return;
1478  SXmlNode_t* node = (SXmlNode_t*) xmlnode;
1479 
1480  Bool_t issingleline = (node->fChild==0);
1481 
1482  if (layout>0) out->Put(' ', level);
1483 
1484  if (node->fType == kXML_COMMENT) {
1485  out->Write("<!--");
1486  out->Write(SXmlNode_t::Name(node));
1487  out->Write("-->");
1488  if (layout>0) out->Put('\n');
1489  return;
1490  } else
1491  if (node->fType == kXML_RAWLINE) {
1492  out->Write(SXmlNode_t::Name(node));
1493  if (layout>0) out->Put('\n');
1494  return;
1495  } else
1496  if (node->fType == kXML_CONTENT) {
1497  out->Write(SXmlNode_t::Name(node));
1498  if (layout>0) out->Put('\n');
1499  return;
1500  }
1501 
1502  out->Put('<');
1503  if (node->fType==kXML_PI_NODE) out->Put('?');
1504 
1505  // we suppose that ns is always first attribute
1506  if ((node->fNs!=0) && (node->fNs!=node->fAttr)) {
1507  out->Write(SXmlAttr_t::Name(node->fNs)+6);
1508  out->Put(':');
1509  }
1510  out->Write(SXmlNode_t::Name(node));
1511 
1512  SXmlAttr_t* attr = node->fAttr;
1513  while (attr!=0) {
1514  out->Put(' ');
1515  char* attrname = SXmlAttr_t::Name(attr);
1516  out->Write(attrname);
1517  out->Write("=\"");
1518  attrname += strlen(attrname) + 1;
1519  OutputValue(attrname, out);
1520  out->Put('\"');
1521  attr = attr->fNext;
1522  }
1523 
1524  // if single line, close node with "/>" and return
1525  if (issingleline) {
1526  if (node->fType==kXML_PI_NODE) out->Write("?>");
1527  else out->Write("/>");
1528  if (layout>0) out->Put('\n');
1529  return;
1530  }
1531 
1532  out->Put('>');
1533 
1534  SXmlNode_t* child = node->fChild;
1535 
1536  if ((child!=0) && (child->fType == kXML_CONTENT) && (child->fNext == 0)) {
1537  // special case when single content node is exists
1538  out->Write(SXmlNode_t::Name(child));
1539  } else {
1540  if (layout>0) out->Put('\n');
1541  while (child!=0) {
1542  SaveNode((XMLNodePointer_t) child, out, layout, level+2);
1543  child = child->fNext;
1544  }
1545  // add starting spaces before closing node
1546  if (layout>0) out->Put(' ',level);
1547  }
1548 
1549  out->Write("</");
1550  // we suppose that ns is always first attribute
1551  if ((node->fNs!=0) && (node->fNs!=node->fAttr)) {
1552  out->Write(SXmlAttr_t::Name(node->fNs)+6);
1553  out->Put(':');
1554  }
1555  out->Write(SXmlNode_t::Name(node));
1556  out->Put('>');
1557  if (layout>0) out->Put('\n');
1558 }
1559 
1560 ////////////////////////////////////////////////////////////////////////////////
1561 /// Tries to construct xml node from input stream. Node should be
1562 /// child of xmlparent node or it can be closing tag of xmlparent.
1563 /// resvalue <= 0 if error
1564 /// resvalue == 1 if this is endnode of parent
1565 /// resvalue == 2 if this is child
1566 
1567 XMLNodePointer_t TXMLEngine::ReadNode(XMLNodePointer_t xmlparent, TXMLInputStream* inp, Int_t& resvalue)
1568 {
1569  resvalue = 0;
1570 
1571  if (inp==0) return 0;
1572  if (!inp->SkipSpaces()) { resvalue = -1; return 0; }
1573  SXmlNode_t* parent = (SXmlNode_t*) xmlparent;
1574 
1575  SXmlNode_t* node = 0;
1576 
1577  // process comments before we start to analyse any node symbols
1578  while (inp->CheckFor("<!--")) {
1579  Int_t commentlen = inp->SearchFor("-->");
1580  if (commentlen<=0) { resvalue = -10; return 0; }
1581 
1582  if (!fSkipComments) {
1583  node = (SXmlNode_t*) AllocateNode(commentlen, xmlparent);
1584  char* nameptr = SXmlNode_t::Name(node);
1585  node->fType = kXML_COMMENT;
1586  strncpy(nameptr, inp->fCurrent, commentlen); // here copy only content, there is no padding 0 at the end
1587  nameptr+=commentlen;
1588  *nameptr = 0; // here we add padding 0 to get normal string
1589  }
1590 
1591  if (!inp->ShiftCurrent(commentlen+3)) { resvalue = -1; return node; }
1592  if (!inp->SkipSpaces() && !inp->EndOfStream()) { resvalue = -1; return node; }
1593 
1594  resvalue = 2;
1595  return node;
1596  }
1597 
1598  if (*inp->fCurrent!='<') {
1599  // here should be reading of element content
1600  // now one can have content at any place of the node, also after childs
1601  if (parent==0) { resvalue = -2; return 0; }
1602  int contlen = inp->LocateContent();
1603  if (contlen<0) return 0;
1604 
1605  SXmlNode_t* contnode = (SXmlNode_t*) AllocateNode(contlen, xmlparent);
1606  contnode->fType = kXML_CONTENT;
1607  char* contptr = SXmlNode_t::Name(contnode);
1608  UnpackSpecialCharacters(contptr, inp->fCurrent, contlen);
1609  if (!inp->ShiftCurrent(contlen)) return 0;
1610 
1611  if (inp->NumEntities() <= 0) {
1612  resvalue = 2;
1613  return contnode;
1614  }
1615 
1616  // analyze content on possible includes only when ENTITY was specified for document
1617 
1618  const char* beg(0), *lastentity(0), *curr(contptr);
1619 
1620  while (*curr != 0) {
1621  if ((beg==0) && (*curr=='&')) beg = curr;
1622  if ((beg==0) || (*curr!=';')) { curr++; continue; }
1623 
1624  TXMLEntity* entity = inp->FindEntity(beg+1, curr - beg - 1);
1625 
1626  if (entity!=0) {
1627 
1628  if (lastentity==0) {
1629  lastentity = contptr;
1630  UnlinkNode(contnode);
1631  }
1632 
1633  if (lastentity!=beg)
1634  AddNodeContent(xmlparent, lastentity, beg - lastentity);
1635 
1636  // printf("Find entity %s in content\n", entity->GetName());
1637  if (entity->IsSystem()) {
1638  XMLDocPointer_t entitydoc = ParseFile(entity->GetTitle());
1639  if (entitydoc == 0) {
1640  resvalue = -14;
1641  return contnode;
1642  }
1643 
1644  XMLNodePointer_t topnode = DocGetRootElement(entitydoc);
1645 
1646  while (topnode!=0) {
1647  XMLNodePointer_t currnode = topnode;
1648  ShiftToNext(topnode, false);
1649  UnlinkNode(currnode);
1650  AddChild(xmlparent, currnode);
1651  }
1652  } else {
1653  AddNodeContent(xmlparent, entity->GetTitle());
1654  }
1655  }
1656 
1657  beg = 0;
1658  curr++;
1659 
1660  lastentity = curr;
1661  }
1662 
1663  if (lastentity!=0) {
1664  // add rest part of the content
1665  if (strlen(lastentity)>0) AddNodeContent(xmlparent,lastentity);
1666  // do not forget to cleanup content node
1667  FreeNode(contnode);
1668  contnode = 0;
1669  }
1670 
1671  resvalue = 2;
1672  return contnode;
1673  } else {
1674  // skip "<" symbol
1675  if (!inp->ShiftCurrent()) return 0;
1676  }
1677 
1678  if (*inp->fCurrent=='/') {
1679  // this is a starting of closing node
1680  if (!inp->ShiftCurrent()) return 0;
1681  if (!inp->SkipSpaces()) return 0;
1682  Int_t len = inp->LocateIdentifier();
1683  if (len<=0) { resvalue = -3; return 0; }
1684 
1685  if (parent==0) { resvalue = -4; return 0; }
1686 
1687  if (strncmp(SXmlNode_t::Name(parent), inp->fCurrent, len)!=0) {
1688  resvalue = -5;
1689  return 0;
1690  }
1691 
1692  if (!inp->ShiftCurrent(len)) return 0;
1693 
1694  if (!inp->SkipSpaces()) return 0;
1695  if (*inp->fCurrent!='>') return 0;
1696  if (!inp->ShiftCurrent()) return 0;
1697 
1698  if (parent->fNs!=0)
1699  TruncateNsExtension((XMLNodePointer_t)parent);
1700 
1701  inp->SkipSpaces(kTRUE); // locate start of next string
1702  resvalue = 1;
1703  return 0;
1704  }
1705 
1706  if (*inp->fCurrent=='!') {
1707  // this is start of DTD reading, only limited number of features are supported
1708  if (!inp->ShiftCurrent()) return 0;
1709  if (!inp->CheckFor("DOCTYPE")) { resvalue = -12; return 0; }
1710  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1711 
1712  // now skip name of the root element - it is not verified at all
1713  Int_t len = inp->LocateIdentifier();
1714  if (len<=0) { resvalue = -13; return 0; }
1715  if (!inp->ShiftCurrent(len)) { resvalue = -13; return 0; }
1716  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1717 
1718  // this is start of reading ENTITIES
1719  if (inp->CheckFor("[")) {
1720  if (!inp->SkipSpaces()) return 0;
1721  while (true) {
1722  if (inp->CheckFor("<!ENTITY")) {
1723  // process ENTITY from DTD
1724  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1725  Int_t namelen = inp->LocateIdentifier();
1726  if (namelen<=0) { resvalue = -13; return 0; }
1727  TString entity_name(inp->fCurrent, namelen);
1728  if (!inp->ShiftCurrent(namelen)) { resvalue = -13; return 0; }
1729  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1730  Bool_t is_system = kFALSE;
1731  if (inp->CheckFor("SYSTEM")) {
1732  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1733  is_system = kTRUE;
1734  }
1735 
1736  char* valuestart = inp->fCurrent;
1737  Int_t valuelen = inp->LocateValue(valuestart, false);
1738  if (valuelen < 2) { resvalue = -13; return 0; }
1739 
1740  TString entity_value(valuestart+1, valuelen-2);
1741 
1742  if (!inp->ShiftCurrent(valuelen)) { resvalue = -13; return 0; }
1743  inp->SkipSpaces();
1744  if (*inp->fCurrent!='>') { resvalue = -13; return 0; }
1745  if (!inp->ShiftCurrent()) { resvalue = -13; return 0; }
1746  inp->SkipSpaces();
1747 
1748  inp->AddEntity(new TXMLEntity(entity_name, entity_value, is_system));
1749  continue;
1750 
1751  // printf("Entity:%s system:%s value:%s\n", entity_name.Data(), is_system ? "true" : "false", entity_value.Data());
1752  }
1753 
1754  if (inp->CheckFor("<!ELEMENT")) {
1755  // process ELEMENT from DTD - dummy at the moment
1756  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1757  Int_t namelen = inp->LocateIdentifier();
1758  if (namelen<=0) { resvalue = -13; return 0; }
1759 
1760  if (!inp->ShiftCurrent(namelen)) { resvalue = -13; return 0; }
1761  if (!inp->SkipSpaces()) { resvalue = -13; return 0; }
1762 
1763  if (!inp->CheckFor("(")) { resvalue = -13; return 0; }
1764  if (inp->SearchFor(")")<=0) { resvalue = -13; return 0; }
1765 
1766  inp->SkipSpaces();
1767  if (*inp->fCurrent!='>') { resvalue = -13; return 0; }
1768  if (!inp->ShiftCurrent()) { resvalue = -13; return 0; }
1769  inp->SkipSpaces();
1770 
1771  continue;
1772  }
1773 
1774  break;
1775  }
1776 
1777  if (!inp->CheckFor("]")) { resvalue = -13; return 0; }
1778  }
1779  inp->SkipSpaces();
1780  if (!inp->CheckFor(">")) { resvalue = -13; return 0; }
1781 
1782  resvalue = 2;
1783  return node;
1784  }
1785 
1786 
1787 
1788  EXmlNodeType nodetype = kXML_NODE;
1789  Bool_t canhaschildren = true;
1790  char endsymbol = '/';
1791 
1792  // this is case of processing instructions node
1793  if (*inp->fCurrent=='?') {
1794  if (!inp->ShiftCurrent()) return 0;
1795  nodetype = kXML_PI_NODE;
1796  canhaschildren = false;
1797  endsymbol = '?';
1798  }
1799 
1800  if (!inp->SkipSpaces()) return 0;
1801  Int_t len = inp->LocateIdentifier();
1802  if (len<=0) return 0;
1803  node = (SXmlNode_t*) AllocateNode(len, xmlparent);
1804  char* nameptr = SXmlNode_t::Name(node);
1805  node->fType = nodetype;
1806 
1807  strncpy(nameptr, inp->fCurrent, len); // here copied content without padding 0
1808  nameptr+=len;
1809  *nameptr = 0; // add 0 to the end
1810 
1811  char* colon = strchr(SXmlNode_t::Name(node),':');
1812  if ((colon!=0) && (parent!=0)) {
1813  *colon = 0;
1814  node->fNs = (SXmlAttr_t*) FindNs(xmlparent, SXmlNode_t::Name(node));
1815  *colon =':';
1816  }
1817 
1818  if (!inp->ShiftCurrent(len)) return 0;
1819 
1820  do {
1821  if (!inp->SkipSpaces()) return 0;
1822 
1823  char nextsymb = *inp->fCurrent;
1824 
1825  if (nextsymb==endsymbol) { // this is end of short node like <node ... />
1826  if (!inp->ShiftCurrent()) return 0;
1827  if (*inp->fCurrent=='>') {
1828  if (!inp->ShiftCurrent()) return 0;
1829 
1830  if (node->fNs!=0)
1831  TruncateNsExtension((XMLNodePointer_t) node);
1832 
1833  inp->SkipSpaces(kTRUE); // locate start of next string
1834  resvalue = 2;
1835  return node;
1836  } else return 0;
1837  } else
1838  if (nextsymb=='>') { // this is end of parent node, lets find all children
1839  if (!canhaschildren) { resvalue = -11; return 0; }
1840 
1841  if (!inp->ShiftCurrent()) return 0;
1842 
1843  do {
1844  ReadNode(node, inp, resvalue);
1845  } while (resvalue==2);
1846 
1847  if (resvalue==1) {
1848  resvalue = 2;
1849  return node;
1850  } else return 0;
1851  } else {
1852  Int_t attrlen = inp->LocateIdentifier();
1853  if (attrlen<=0) { resvalue = -6; return 0; }
1854 
1855  char* valuestart = inp->fCurrent+attrlen;
1856 
1857  int valuelen = inp->LocateValue(valuestart, true);
1858  if (valuelen<3) { resvalue = -7; return 0; }
1859 
1860  SXmlAttr_t* attr = (SXmlAttr_t*) AllocateAttr(attrlen, valuelen-3, (XMLNodePointer_t) node);
1861 
1862  char* attrname = SXmlAttr_t::Name(attr);
1863  strncpy(attrname, inp->fCurrent, attrlen);
1864  attrname+=attrlen;
1865  *attrname = 0;
1866  attrname++;
1867  UnpackSpecialCharacters(attrname, valuestart+2, valuelen-3);
1868 
1869  if (!inp->ShiftCurrent(attrlen+valuelen)) return 0;
1870 
1871  attrname = SXmlAttr_t::Name(attr);
1872 
1873  if ((strlen(attrname)>6) && (strstr(attrname,"xmlns:")==attrname)) {
1874  if (strcmp(SXmlNode_t::Name(node), attrname + 6)!=0) {
1875  resvalue = -8;
1876  //return 0;
1877  }
1878  if (node->fNs!=0) {
1879  resvalue = -9;
1880  //return 0;
1881  }
1882  node->fNs = attr;
1883  }
1884  }
1885  } while (true);
1886 
1887  return 0;
1888 }
1889 
1890 ////////////////////////////////////////////////////////////////////////////////
1891 /// Displays xml parsing error
1892 
1893 void TXMLEngine::DisplayError(Int_t error, Int_t linenumber)
1894 {
1895  switch(error) {
1896  case -14: Error("ParseFile", "Error include external XML file at line %d", linenumber); break;
1897  case -13: Error("ParseFile", "Error processing DTD part of XML file at line %d", linenumber); break;
1898  case -12: Error("ParseFile", "DOCTYPE missing after <! at line %d", linenumber); break;
1899  case -11: Error("ParseFile", "Node cannot be closed with > symbol at line %d, for instance <?xml ... ?> node", linenumber); break;
1900  case -10: Error("ParseFile", "Error in xml comments definition at line %d, must be <!-- comments -->", linenumber); break;
1901  case -9: Error("ParseFile", "Multiple name space definitions not allowed, line %d", linenumber); break;
1902  case -8: Error("ParseFile", "Invalid namespace specification, line %d", linenumber); break;
1903  case -7: Error("ParseFile", "Invalid attribute value, line %d", linenumber); break;
1904  case -6: Error("ParseFile", "Invalid identifier for node attribute, line %d", linenumber); break;
1905  case -5: Error("ParseFile", "Mismatch between open and close nodes, line %d", linenumber); break;
1906  case -4: Error("ParseFile", "Unexpected close node, line %d", linenumber); break;
1907  case -3: Error("ParseFile", "Valid identifier for close node is missing, line %d", linenumber); break;
1908  case -2: Error("ParseFile", "No multiple content entries allowed, line %d", linenumber); break;
1909  case -1: Error("ParseFile", "Unexpected end of xml file"); break;
1910  default: Error("ParseFile", "XML syntax error at line %d", linenumber); break;
1911  }
1912 
1913 }
char * Makestr(const char *str)
creates char* variable with copy of provided string
XMLDocPointer_t ParseStream(TXMLInputStream *input)
parses content of the stream and tries to produce xml structures
An array of TObjects.
Definition: TObjArray.h:37
void FreeAttr(XMLNodePointer_t xmlnode, const char *name)
remove attribute from xmlnode
Definition: TXMLEngine.cxx:526
XMLNsPointer_t GetNS(XMLNodePointer_t xmlnode)
return namespace attribute (if exists)
Definition: TXMLEngine.cxx:665
TLine * line
void SaveNode(XMLNodePointer_t xmlnode, TXMLOutputStream *out, Int_t layout, Int_t level)
stream data of xmlnode to output
Bool_t AddStyleSheet(XMLNodePointer_t parent, const char *href, const char *type="text/css", const char *title=0, int alternate=-1, const char *media=0, const char *charset=0)
Adds style sheet definition to the specified node Creates <?xml-stylesheet alternate="yes" title="com...
Definition: TXMLEngine.cxx:808
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
XMLDocPointer_t NewDoc(const char *version="1.0")
creates new xml document with provided version
#define GoodStartSymbol(symb)
Definition: TXMLEngine.cxx:366
TXMLEngine()
if true, do not create comments nodes in document during parsing
Definition: TXMLEngine.cxx:430
XMLNodePointer_t GetNext(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
return next to xmlnode node if realnode==kTRUE, any special nodes in between will be skipped ...
Basic string class.
Definition: TString.h:129
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Bool_t AddComment(XMLNodePointer_t parent, const char *comment)
Adds comment line to the node.
Definition: TXMLEngine.cxx:734
XMLNsPointer_t FindNs(XMLNodePointer_t xmlnode, const char *nsname)
define if namespace of that name exists for xmlnode
#define malloc
Definition: civetweb.c:818
XMLAttrPointer_t GetNextAttr(XMLAttrPointer_t xmlattr)
return next attribute in the list
Definition: TXMLEngine.cxx:582
void FreeDoc(XMLDocPointer_t xmldoc)
frees allocated document data and deletes document itself
void UnlinkFreeNode(XMLNodePointer_t xmlnode)
combined operation. Unlink node and free used memory
Definition: TXMLEngine.cxx:921
XMLAttrPointer_t NewIntAttr(XMLNodePointer_t xmlnode, const char *name, Int_t value)
create node attribute with integer value
Definition: TXMLEngine.cxx:514
const char * Name
Definition: TXMLSetup.cxx:67
const char * GetNodeContent(XMLNodePointer_t xmlnode)
get contents (if any) of xml node
Definition: TXMLEngine.cxx:938
EXmlNodeType
Definition: TXMLEngine.cxx:40
void DisplayError(Int_t error, Int_t linenumber)
Displays xml parsing error.
void FreeAllAttr(XMLNodePointer_t xmlnode)
Free all attributes of the node.
Definition: TXMLEngine.cxx:550
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
void * XMLDocPointer_t
Definition: TXMLEngine.h:20
void DocSetRootElement(XMLDocPointer_t xmldoc, XMLNodePointer_t xmlnode)
set main (root) node for document
XMLNsPointer_t NewNS(XMLNodePointer_t xmlnode, const char *reference, const char *name=0)
create namespace attribute for xmlnode.
Definition: TXMLEngine.cxx:641
TString & Append(const char *cs)
Definition: TString.h:497
const int maxsize
XMLDocPointer_t ParseString(const char *xmlstring)
parses content of string and tries to produce xml structures
#define realloc
Definition: civetweb.c:820
Bool_t IsEmptyNode(XMLNodePointer_t xmlnode)
return kTRUE is this is node with special data like comments to data processing instructions ...
void Error(const char *location, const char *msgfmt,...)
const char * GetNodeName(XMLNodePointer_t xmlnode)
returns name of xmlnode
Definition: TXMLEngine.cxx:930
XMLAttrPointer_t AllocateAttr(int namelen, int valuelen, XMLNodePointer_t xmlnode)
Allocate new attribute with specified name length and value length.
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:528
void SaveDoc(XMLDocPointer_t xmldoc, const char *filename, Int_t layout=1)
store document content to file if layout<=0, no any spaces or newlines will be placed between xmlnode...
void AddChild(XMLNodePointer_t parent, XMLNodePointer_t child)
add child element to xmlnode
Definition: TXMLEngine.cxx:697
void ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode=kTRUE)
shifts specified node to next if realnode==kTRUE, any special nodes in between will be skipped ...
Bool_t AddRawLine(XMLNodePointer_t parent, const char *line)
Add just line into xml file Line should has correct xml syntax that later it can be decoded by xml pa...
Definition: TXMLEngine.cxx:769
void SetNodeContent(XMLNodePointer_t xmlnode, const char *content, Int_t len=0)
set content of the xml node if old node content was exists, it will be replaced
Definition: TXMLEngine.cxx:953
char * Makenstr(const char *start, int len)
creates char* variable with copy of len symbols from provided string
Bool_t IsCommentNode(XMLNodePointer_t xmlnode)
return kTRUE is this is special node with content
const char * GetAttrValue(XMLAttrPointer_t xmlattr)
return value of attribute
Definition: TXMLEngine.cxx:603
XMLAttrPointer_t GetFirstAttr(XMLNodePointer_t xmlnode)
return first attribute in the list, namespace (if exists) will be skiped
Definition: TXMLEngine.cxx:568
void * XMLNodePointer_t
Definition: TXMLEngine.h:17
Bool_t AddDocStyleSheet(XMLDocPointer_t xmldoc, const char *href, const char *type="text/css", const char *title=0, int alternate=-1, const char *media=0, const char *charset=0)
Add style sheet definition on the top of document.
Definition: TXMLEngine.cxx:843
void SkipEmpty(XMLNodePointer_t &xmlnode)
Skip all current empty nodes and locate on first "true" node.
Bool_t IsXmlNode(XMLNodePointer_t xmlnode)
return kTRUE is this is normal xml node
const Bool_t kFALSE
Definition: RtypesCore.h:92
PyObject * fType
Bool_t HasAttr(XMLNodePointer_t xmlnode, const char *name)
checks if node has attribute of specified name
Definition: TXMLEngine.cxx:446
Bool_t AddDocRawLine(XMLDocPointer_t xmldoc, const char *line)
Add just line on the top of xml document Line should has correct xml syntax that later it can be deco...
Definition: TXMLEngine.cxx:785
XMLDocPointer_t ParseFile(const char *filename, Int_t maxbuf=100000)
Parses content of file and tries to produce xml structures.
void AddChildFirst(XMLNodePointer_t parent, XMLNodePointer_t child)
add node as first child
Definition: TXMLEngine.cxx:717
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:488
void * XMLAttrPointer_t
Definition: TXMLEngine.h:19
void CleanNode(XMLNodePointer_t xmlnode)
remove all children node from xmlnode
#define ClassImp(name)
Definition: Rtypes.h:336
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
returns value of attribute for xmlnode
Definition: TXMLEngine.cxx:460
void SaveSingleNode(XMLNodePointer_t xmlnode, TString *res, Int_t layout=1)
convert single xml node (and its child node) to string if layout<=0, no any spaces or newlines will b...
Bool_t AddDocComment(XMLDocPointer_t xmldoc, const char *comment)
add comment line to the top of the document
Definition: TXMLEngine.cxx:750
int type
Definition: TGX11.cxx:120
#define free
Definition: civetweb.c:821
void TruncateNsExtension(XMLNodePointer_t xmlnode)
removes namespace extension of nodename
void FreeNode(XMLNodePointer_t xmlnode)
release all memory, allocated fro this node and destroyes node itself
Definition: TXMLEngine.cxx:893
XMLNodePointer_t ReadNode(XMLNodePointer_t xmlparent, TXMLInputStream *inp, Int_t &resvalue)
Tries to construct xml node from input stream.
Bool_t ValidateVersion(XMLDocPointer_t doc, const char *version=0)
check that first node is xml processing instruction with correct xml version number ...
void * XMLNsPointer_t
Definition: TXMLEngine.h:18
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xml node
Definition: TXMLEngine.cxx:993
XMLNodePointer_t GetParent(XMLNodePointer_t xmlnode)
returns parent of xmlnode
void UnpackSpecialCharacters(char *target, const char *source, int srclen)
unpack special symbols, used in xml syntax to code characters these symbols: &#39;<&#39; - &lt, &#39;>&#39; - &gt, &#39;&&#39; - &amp, &#39;"...
const char * GetNSName(XMLNsPointer_t ns)
return name id of namespace
Definition: TXMLEngine.cxx:676
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=0)
create new child element for parent node
Definition: TXMLEngine.cxx:614
XMLNodePointer_t DocGetRootElement(XMLDocPointer_t xmldoc)
returns root node of document
void UnlinkNode(XMLNodePointer_t node)
unlink (dettach) xml node from parent
Definition: TXMLEngine.cxx:867
#define snprintf
Definition: civetweb.c:822
Int_t GetIntAttr(XMLNodePointer_t node, const char *name)
returns value of attribute as integer
Definition: TXMLEngine.cxx:475
Bool_t IsContentNode(XMLNodePointer_t xmlnode)
return kTRUE is this is special node with content
void Add(TObject *obj)
Definition: TObjArray.h:73
void AddNodeContent(XMLNodePointer_t xmlnode, const char *content, Int_t len=0)
add new content of the xml node old content will be preserved, one could mix content with child nodes...
Definition: TXMLEngine.cxx:977
Definition: first.py:1
XMLNodePointer_t ReadSingleNode(const char *src)
read single xml node from provided string
virtual ~TXMLEngine()
destructor for TXMLEngine object
Definition: TXMLEngine.cxx:439
void OutputValue(char *value, TXMLOutputStream *out)
output value to output stream if symbols &#39;<&#39; &#39;&&#39; &#39;>&#39; &#39;"&#39; &#39;&#39;&#39; appears in the string, they will be encoded to appropriate xml symbols: &lt, &amp, &gt, &quot, &apos
const char * GetAttrName(XMLAttrPointer_t xmlattr)
return name of the attribute
Definition: TXMLEngine.cxx:592
const Bool_t kTRUE
Definition: RtypesCore.h:91
const Int_t n
Definition: legend1.C:16
XMLNodePointer_t AllocateNode(int namelen, XMLNodePointer_t parent)
Allocates new xml node with specified namelength.
const char * GetNSReference(XMLNsPointer_t ns)
return reference id of namespace
Definition: TXMLEngine.cxx:688
const char * cnt
Definition: TXMLSetup.cxx:75
void AssignDtd(XMLDocPointer_t xmldoc, const char *dtdname, const char *rootname)
assignes dtd filename to document