Merge branch 'master', remote branch 'origin' into TPCdev
[u/mrichter/AliRoot.git] / ANALYSIS / AliXMLParser.cxx
1 /* 
2 Author : Harsh Arora (harsh.arora@cern.ch)
3
4    
5 AliXMLParser
6 ---------
7
8 AliXMLParser is a tool to parse XML file from URL or path and store it in trees.
9
10 */
11
12 #include "AliXMLParser.h"
13
14 #include <Riostream.h>
15 #include "TTree.h"
16 #include "TBranch.h"
17 #include "TWebFile.h"
18 #include <iostream>
19 #include <cstdlib>
20 #include <TList.h>
21 #include <TString.h>
22
23 using std::cerr;
24 using std::cout;
25 using std::endl;
26
27 ClassImp(AliXMLParser);
28
29 AliXMLParser::AliXMLParser():
30    fTreeList(0),
31    fTableTag(0),
32    fInsideTree(kFALSE),
33    fNumTokens(0),
34    fEntries(0),
35    fVal(0),
36    fNumTrees(0),
37    fError(kFALSE)
38 {
39    //Default Contructor
40
41    fEntries = new TList();
42    fVal = new TList();
43    fTreeList = new TList();
44    fInsideTree = kFALSE;
45    fNumTrees = 0;
46    fNumTokens = -1;
47    fError = kFALSE;
48
49    fEntries->SetOwner(kTRUE);
50    fVal->SetOwner(kTRUE);
51    fTreeList->SetOwner(kTRUE);
52 }
53
54 AliXMLParser::AliXMLParser(const AliXMLParser& obj):
55    fTreeList(0),
56    fTableTag(0),
57    fInsideTree(kFALSE),
58    fNumTokens(0),
59    fEntries(0),
60    fVal(0),
61    fNumTrees(0),
62    fError(kFALSE)
63 {
64    //Copy Contructor
65    fTreeList = obj.fTreeList;
66    fTableTag = obj.fTableTag;
67    fInsideTree = obj.fInsideTree;
68    fNumTokens = obj.fNumTokens;
69    fEntries = obj.fEntries;
70    fVal = obj.fVal;
71    fNumTrees = obj.fNumTrees;
72    fError = obj.fError;
73 }
74
75 AliXMLParser& AliXMLParser::operator=(const AliXMLParser& other)
76 {
77    //Assignment
78    if(this != &other)
79    {
80       fTreeList = other.fTreeList;
81       fTableTag = other.fTableTag;
82       fInsideTree = other.fInsideTree;
83       fNumTokens = other.fNumTokens;
84       fEntries = other.fEntries;
85       fVal = other.fVal;
86       fNumTrees = other.fNumTrees;
87       fError = other.fError;
88    }
89    return *this;
90 }
91
92 void AliXMLParser::OnStartDocument() {}
93
94 int AliXMLParser::GetEntryIndex(TString entry_name) //Finds the attribute index by name
95 {
96    int i;
97    for(i=0;i<=fNumTokens;i++)
98    {
99       if(entry_name.EqualTo(*(TString *)(fEntries->At(i))))
100          return i;
101    }
102    return -1;
103 }
104
105 void AliXMLParser::OnStartElement(const char *name, const TList *attributes) //Stores Parsed XML in a Tree
106 {
107    int n,i;
108    TString tree_symbol = "roottreename";
109    TString var(name);
110    TString temp("");
111    TXMLAttr *attr;
112    TIter next(attributes);
113    TBranch *branch;
114    TTree *curr_tree;
115
116    if((attr = (TXMLAttr*) next()))
117    {
118       if((!fInsideTree) && tree_symbol.EqualTo(attr->GetName())) //If tag found, Enter a new tree
119       {
120          fTableTag = name;
121          fNumTrees++;
122          fTreeList->Add((TObject *)(new TTree(attr->GetValue(),attr->GetValue())));
123          fInsideTree = kTRUE;
124       }
125       else if(fInsideTree)
126       {
127          curr_tree=(TTree *)(fTreeList->At(fNumTrees-1));
128          do
129          {
130             if(!(curr_tree->GetBranch(attr->GetName())))
131           
132             {
133                TString var_type = attr->GetName();
134                var_type += "/C";
135                fNumTokens++;
136
137                fEntries->Add((TObject *)(new TString(attr->GetName())));
138
139                fVal->Add((TObject *)(new TString(temp)));
140
141                //Adding Attributes as branches of TTree
142                branch = curr_tree->Branch(attr->GetName(), (void *)(((TString *)(fVal->At(fNumTokens)))->Data()), var_type);
143                n = curr_tree->GetEntries();
144                if(n > 0)
145                {
146                   (*(TString *)(fVal->At(fNumTokens))) = temp;
147                   for(i=0;i<n;i++)
148                      branch->Fill();
149                }
150
151             }
152
153             (*(TString *)(fVal->At(GetEntryIndex(attr->GetName())))) = attr->GetValue();
154
155            
156          } while ((attr = (TXMLAttr*) next()));
157          curr_tree->Fill(); //Fill the tree with attribute values
158          for(i=0;i<=fNumTokens;i++)
159          {
160             (*(TString *)(fVal->At(i))) = temp;
161          }
162       }
163    }
164 }
165
166       
167    
168 void AliXMLParser::OnEndElement(const char *name)
169 {
170    //if tag closes, re-initialize everything for a new tree
171    if(fTableTag.EqualTo(name))
172    {
173       fInsideTree = kFALSE;
174       fEntries->Clear("nodelete");
175       fVal->Clear("nodelete");
176       fNumTokens=-1;
177    }
178 }
179
180 void AliXMLParser::OnCharacters(const char *) {} 
181
182 void AliXMLParser::OnComment(const char *) {}
183
184 void AliXMLParser::OnWarning(const char *warning) 
185 {
186    cout << "Warning in XML: " << warning << endl;
187 }
188
189 void AliXMLParser::OnError(const char *error) 
190
191    fError = kTRUE;
192    cerr << "Error in XML: " << error << endl;
193 }
194
195 void AliXMLParser::OnFatalError(const char *error)
196
197    fError = kTRUE;
198    cerr << "FatalError in XML: " << error << endl;
199 }
200
201 void AliXMLParser::OnCdataBlock(const char *, Int_t ) {}
202
203 void AliXMLParser::OnEndDocument() {}
204
205 AliXMLParser::~AliXMLParser()
206 {
207    delete fEntries;
208    delete fVal;
209    delete fTreeList;
210 }
211
212
213 TList* AliXMLParser::GetTreesFromXML(TString file) //Returns List of Trees by parsing local XML file
214 {
215    TSAXParser *saxParser = new TSAXParser();
216    saxParser->ConnectToHandler("AliXMLParser", this);
217    if(!TFile::Open(file)) 
218    {
219       cerr << "File not found" << endl;
220       return 0x0;
221    }
222    saxParser->ParseFile(file);
223    delete saxParser;
224    if (fError) return 0x0;
225    return fTreeList;
226 }
227
228 TList *AliXMLParser::GetTreesFromURL(TString host) //Returns List of Trees by parsing remote XML file
229 {
230    char *buf;
231    int size;
232    TSAXParser *saxParser = new TSAXParser();
233    saxParser->ConnectToHandler("AliXMLParser", this);
234    host += "&filetype=raw";
235    TFile *file = TFile::Open(host);
236    if (!file)
237    {
238       cerr << "Invalid URL" << endl;
239       return 0x0;
240    }
241    size=file->GetSize();
242    buf = (char *)malloc(size+1);
243    file->ReadBuffer(buf, size);
244    saxParser->ParseBuffer(buf,size);
245    delete saxParser;
246    free(buf);
247    if (fError) return 0x0;
248    return fTreeList;
249 }