]>
Commit | Line | Data |
---|---|---|
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 | } |