SNAP Library 6.0, User Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
xml.cpp
Go to the documentation of this file.
1 // Xml-Object-Saving
4 
5 TStr TXmlObjSer::GetTagNm(const TStr& TypeNm){
6  TStr& XmlTagNm=TypeNmToTagNmH.AddDat(TypeNm);
7  if (XmlTagNm.Empty()){
8  TChA XmlTagChA=TypeNm;
9  for (int ChN=0; ChN<XmlTagChA.Len(); ChN++){
10  char Ch=XmlTagChA[ChN];
11  if (!((('A'<=Ch)&&(Ch<='Z'))||(('a'<=Ch)&&(Ch<='z'))||(('0'<=Ch)&&(Ch<='9')))){
12  XmlTagChA.PutCh(ChN, '_');
13  }
14  }
15  while ((XmlTagChA.Len()>0)&&(XmlTagChA.LastCh()=='_')){
16  XmlTagChA.Pop();}
17  XmlTagNm=XmlTagChA;
18  }
19  return XmlTagNm;
20 }
21 
23  const PXmlTok& XmlTok, const TStr& Nm, const TStr& TypeNm){
24  // check if the token is full
25  EAssertR(!XmlTok.Empty(), "Xml-Token Empty");
26  // if name is empty then tag=type else tag=name
27  if (!Nm.Empty()){
28  // check if the token is tag
29  if (!XmlTok->IsTag()){
30  TStr ArgStr1="Expected: Tag";
31  TStr ArgStr2=TStr("Found: ")+XmlTok->GetSymStr();
32  TExcept::Throw("Invalid Xml-Token", ArgStr1, ArgStr2);
33  }
34  if (Nm!="-"){
35  // check if the tag is correct
36  if (!XmlTok->IsTag(Nm)){
37  TStr ArgStr1=TStr("Expected: ")+Nm;
38  TStr ArgStr2=TStr("Found: ")+XmlTok->GetStr();
39  TExcept::Throw("Invalid Xml-Tag", ArgStr1, ArgStr2);
40  }
41  // check if the type is correct
42  TStr TypeArgVal=XmlTok->GetStrArgVal("Type");
43  if (TypeArgVal!=TypeNm){
44  TStr ArgStr1=TStr("Expected: ")+TypeNm;
45  TStr ArgStr2=TStr("Found: ")+TypeArgVal;
46  TExcept::Throw("Invalid Xml-Type", ArgStr1, ArgStr2);
47  }
48  }
49  } else {
50  // check if the tag is correct
51  if (!XmlTok->IsTag(TypeNm)){
52  TStr ArgStr1=TStr("Expected: ")+TypeNm;
53  TStr ArgStr2=TStr("Found: ")+XmlTok->GetSymStr();
54  TExcept::Throw("Invalid Xml-Type-Tag", ArgStr1, ArgStr2);
55  }
56  }
57 }
58 
59 bool TXmlObjSer::GetBoolArg(const PXmlTok& XmlTok, const TStr& Nm){
60  TStr ValStr;
61  if (XmlTok->IsArg(Nm, ValStr)){
62  bool Val;
63  if (ValStr.IsBool(Val)){
64  return Val;
65  } else {
66  TExcept::Throw("Invalid Xml-Argument Boolean-Value", Nm, ValStr);
67  }
68  } else {
69  TExcept::Throw("Xml-Argument Missing", Nm);
70  }
71  Fail; return 0;
72 }
73 
74 int TXmlObjSer::GetIntArg(const PXmlTok& XmlTok, const TStr& Nm){
75  TStr ValStr;
76  if (XmlTok->IsArg(Nm, ValStr)){
77  int Val;
78  if (ValStr.IsInt(Val)){
79  return Val;
80  } else {
81  TExcept::Throw("Invalid Xml-Argument Integer-Value", Nm, ValStr);
82  }
83  } else {
84  TExcept::Throw("Xml-Argument Missing", Nm);
85  }
86  Fail; return 0;
87 }
88 
89 int64 TXmlObjSer::GetInt64Arg(const PXmlTok& XmlTok, const TStr& Nm){
90  TStr ValStr;
91  if (XmlTok->IsArg(Nm, ValStr)){
92  int64 Val;
93  if (ValStr.IsInt64(Val)){
94  return Val;
95  } else {
96  TExcept::Throw("Invalid Xml-Argument Integer64-Value", Nm, ValStr);
97  }
98  } else {
99  TExcept::Throw("Xml-Argument Missing", Nm);
100  }
101  Fail; return 0;
102 }
103 
104 double TXmlObjSer::GetFltArg(const PXmlTok& XmlTok, const TStr& Nm){
105  TStr ValStr;
106  if (XmlTok->IsArg(Nm, ValStr)){
107  double Val;
108  if (ValStr.IsFlt(Val)){
109  return Val;
110  } else {
111  TExcept::Throw("Invalid Xml-Argument Double-Value", Nm, ValStr);
112  }
113  } else {
114  TExcept::Throw("Xml-Argument Missing", Nm);
115  }
116  Fail; return 0;
117 }
118 
120 // Xml-Object-Serialization-Tag-Name
122  TSOut& _SOut, const bool& ETagP,
123  const TStr& Nm, const TStr& TypeNm,
124  const TStr& ArgNm, const TStr& ArgVal):
125  TagNm(), SOut(&_SOut){
126  if (Nm!="-"){
127  SOut->PutCh('<');
128  if (Nm.Empty()){
129  SOut->PutStr(TagNm=TypeNm);
130  } else {
131  SOut->PutStr(TagNm=Nm);
132  SOut->PutStr(" Type=\""); SOut->PutStr(TypeNm); SOut->PutCh('"');
133  }
134  if (!ArgNm.Empty()){
135  SOut->PutCh(' '); SOut->PutStr(ArgNm); SOut->PutCh('=');
136  SOut->PutCh('"'); SOut->PutStr(ArgVal); SOut->PutCh('"');
137  }
138  if (ETagP){
139  SOut->PutCh('/'); TagNm="";}
140  SOut->PutCh('>');
141  }
142 }
143 
145  TSOut& _SOut, const bool& ETagP,
146  const TStr& Nm, const TStr& TypeNm,
147  const TStr& ArgNm1, const TStr& ArgVal1,
148  const TStr& ArgNm2, const TStr& ArgVal2,
149  const TStr& ArgNm3, const TStr& ArgVal3,
150  const TStr& ArgNm4, const TStr& ArgVal4):
151  TagNm(), SOut(&_SOut){
152  if (Nm!="-"){
153  SOut->PutCh('<');
154  if (Nm.Empty()){
155  SOut->PutStr(TagNm=TypeNm);
156  } else {
157  SOut->PutStr(TagNm=Nm);
158  SOut->PutStr(" Type=\""); SOut->PutStr(TypeNm); SOut->PutCh('"');
159  }
160  if (!ArgNm1.Empty()){
161  SOut->PutCh(' '); SOut->PutStr(ArgNm1); SOut->PutCh('=');
162  SOut->PutCh('"'); SOut->PutStr(ArgVal1); SOut->PutCh('"');
163  }
164  if (!ArgNm2.Empty()){
165  SOut->PutCh(' '); SOut->PutStr(ArgNm2); SOut->PutCh('=');
166  SOut->PutCh('"'); SOut->PutStr(ArgVal2); SOut->PutCh('"');
167  }
168  if (!ArgNm3.Empty()){
169  SOut->PutCh(' '); SOut->PutStr(ArgNm3); SOut->PutCh('=');
170  SOut->PutCh('"'); SOut->PutStr(ArgVal3); SOut->PutCh('"');
171  }
172  if (!ArgNm4.Empty()){
173  SOut->PutCh(' '); SOut->PutStr(ArgNm4); SOut->PutCh('=');
174  SOut->PutCh('"'); SOut->PutStr(ArgVal4); SOut->PutCh('"');
175  }
176  if (ETagP){
177  SOut->PutCh('/'); TagNm="";}
178  SOut->PutCh('>');
179  }
180 }
181 
183  if (!TagNm.Empty()){
184  SOut->PutCh('<'); SOut->PutCh('/'); SOut->PutStr(TagNm); SOut->PutCh('>');
185  }
186 }
187 
189 // Xml-Chars
190 void TXmlChDef::SetChTy(TBSet& ChSet, const int& MnCh, const int& MxCh){
191  IAssert((0<=MnCh)&&((MxCh==-1)||((MnCh<=MxCh)&&(MxCh<Chs))));
192  ChSet.Incl(MnCh);
193  for (int Ch=MnCh+1; Ch<=MxCh; Ch++){
194  ChSet.Incl(Ch);}
195 }
196 
197 void TXmlChDef::SetChTy(TBSet& ChSet, const TStr& Str){
198  for (int ChN=0; ChN<Str.Len(); ChN++){
199  uchar Ch=Str[ChN];
200  ChSet.Incl(Ch);
201  }
202 }
203 
204 void TXmlChDef::SetEntityVal(const TStr& Nm, const TStr& Val){
205  EntityNmToValH.AddDat(Nm, Val);
206 }
207 
209  Chs(TUCh::Vals),
210  CharChSet(), CombChSet(), ExtChSet(),
211  LetterChSet(), DigitChSet(), NameChSet(), PubidChSet(),
212  EntityNmToValH(100){
213 
214  // Character-Sets
215  // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | ...
216  CharChSet.Gen(Chs);
217  // ... because of DMoz (temporary patch)
218  SetChTy(CharChSet, 0x1); SetChTy(CharChSet, 0x3); SetChTy(CharChSet, 0x6);
220  // regular characters
221  SetChTy(CharChSet, 0x9); SetChTy(CharChSet, 0xA); SetChTy(CharChSet, 0xD);
222  SetChTy(CharChSet, 0x20, TUCh::Mx);
223  // BaseChar ::= [#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] |
224  // [#x00D8-#x00F6] | [#x00F8-#x00FF] | ...
225  TBSet BaseChSet(Chs);
226  SetChTy(BaseChSet, 0x41, 0x5A); SetChTy(BaseChSet, 0x61, 0x7A);
227  SetChTy(BaseChSet, 0xC0, 0xD6); SetChTy(BaseChSet, 0xD8, 0xF6);
228  SetChTy(BaseChSet, 0xF8, 0xFF);
229  // Ideographic ::= ...
230  TBSet IdeoChSet(Chs);
231  // CombiningChar ::= ...
232  CombChSet.Gen(Chs);
233  // Extender ::= #x00B7 | ...
234  ExtChSet.Gen(Chs);
235  SetChTy(ExtChSet, 0xB7);
236  // Letter ::= BaseChar | Ideographic
237  LetterChSet=BaseChSet|IdeoChSet;
238  // Digit ::= [#x0030-#x0039] | ...
239  DigitChSet.Gen(Chs);
240  SetChTy(DigitChSet, 0x30, 0x39);
241  // NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar
243  uchar('.')|uchar('-')|uchar('_')|uchar(':')|CombChSet;
244  // PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
245  PubidChSet.Gen(Chs);
246  SetChTy(PubidChSet, 0x20); SetChTy(PubidChSet, 0xD); SetChTy(PubidChSet, 0xA);
247  SetChTy(PubidChSet, 'a', 'z'); SetChTy(PubidChSet, 'A', 'Z');
248  SetChTy(PubidChSet, '0', '9'); SetChTy(PubidChSet, "-'()+,./:=?;!*#@$_%");
249 
250  // Standard-Entity-Sequences
251  SetEntityVal("amp", "&");
252  SetEntityVal("lt", "<"); SetEntityVal("gt", ">");
253  SetEntityVal("apos", "'"); SetEntityVal("quot", "\"");
254 }
255 
257 // Xml-Lexical
259 
262  PrevCh=Ch;
263  if (ChStack.Empty()){Ch=(RSIn.Eof()) ? TCh::EofCh : RSIn.GetCh();}
264  else {Ch=ChStack.Pop();}
265  ChN++; if (Ch==TCh::LfCh){LnN++; LnChN=0;} else {LnChN++;}
266  //putchar(Ch);
267  return Ch;
268 }
269 
271  if (Spacing==xspIntact){
272  } else
273  if (Spacing==xspPreserve){
274  int SrcChN=0; int DstChN=0;
275  while (SrcChN<TxtChA.Len()){
276  if (TxtChA[SrcChN]==TCh::CrCh){
277  TxtChA.PutCh(DstChN, TCh::LfCh); SrcChN++; DstChN++;
278  if ((SrcChN<TxtChA.Len())&&(TxtChA[SrcChN]==TCh::LfCh)){SrcChN++;}
279  } else {
280  if (SrcChN!=DstChN){
281  TxtChA.PutCh(DstChN, TxtChA[SrcChN]);}
282  SrcChN++; DstChN++;
283  }
284  }
285  TxtChA.Trunc(DstChN);
286  } else
287  if (Spacing==xspSeparate){
288  // squeeze series of white-spaces to single space
289  int SrcChN=0; int DstChN=0;
290  while (SrcChN<TxtChA.Len()){
291  if (ChDef.IsWs(TxtChA[SrcChN])){
292  if ((DstChN>0)&&(TxtChA[DstChN-1]==' ')){
293  SrcChN++;
294  } else {
295  TxtChA.PutCh(DstChN, ' ');
296  SrcChN++; DstChN++;
297  }
298  } else {
299  TxtChA.PutCh(DstChN, TxtChA[SrcChN]);
300  SrcChN++; DstChN++;
301  }
302  }
303  TxtChA.Trunc(DstChN);
304  } else
305  if (Spacing==xspTruncate){
306  // cut leading and trailing white-spaces and
307  // squeeze series of white-spaces to single space
308  int SrcChN=0; int DstChN=0;
309  while (SrcChN<TxtChA.Len()){
310  if (ChDef.IsWs(TxtChA[SrcChN])){
311  if ((DstChN>0)&&(TxtChA[DstChN-1]==' ')){
312  SrcChN++;
313  } else {
314  TxtChA.PutCh(DstChN, ' ');
315  SrcChN++; DstChN++;
316  }
317  } else {
318  TxtChA.PutCh(DstChN, TxtChA[SrcChN]);
319  SrcChN++; DstChN++;
320  }
321  }
322  TxtChA.Trunc(DstChN);
323  // delete trailing white-spaces
324  while ((TxtChA.Len()>0)&&(ChDef.IsWs(TxtChA.LastCh()))){
325  TxtChA.Pop();}
326  } else {
327  Fail;
328  }
329 }
330 
331 void TXmlLx::GetWs(const bool& IsRq){
332  // [3] S ::= (#x20 | #x9 | #xD | #xA)+
333  int WSpaces=0; TxtChA.Clr();
334  while (ChDef.IsWs(Ch)){
335  WSpaces++; TxtChA+=Ch; GetCh();}
336  if (IsRq&&(WSpaces==0)){
337  EThrow("White-space required.");}
338 }
339 
341  // [67] Reference ::= EntityRef | CharRef
342  if (Ch=='#'){
343  // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
344  TChA RefChA; int RefCd=0;
345  if (GetCh()=='x'){
346  // hex-decimal character code
347  forever {
348  GetCh();
349  if (TCh::IsHex(Ch)){
350  RefChA+=Ch;
351  RefCd=RefCd*16+TCh::GetHex(Ch);
352  } else {
353  break;
354  }
355  }
356  } else {
357  // decimal character code
358  forever {
359  if (TCh::IsNum(Ch)){
360  RefChA+=Ch;
361  RefCd=RefCd*10+TCh::GetNum(Ch);
362  } else {
363  break;
364  }
365  GetCh();
366  }
367  }
368  if ((!RefChA.Empty())&&(Ch==';')){
369  GetCh();
370  if (RefCd < 0x80) {
371  // 8-bit char
372  uchar RefCh=uchar(RefCd);
373  return TStr(RefCh);
374  } else {
375  TStr ResStr = TUnicode::EncodeUtf8(RefCd);
376  return ResStr;
377  }
378  } else {
379  EThrow("Invalid Char-Reference."); Fail; return TStr();
380  }
381  } else {
382  // [68] EntityRef ::= '&' Name ';'
383  TStr EntityNm=GetName();
384  if ((!EntityNm.Empty())&&(Ch==';')){
385  GetCh();
386  TStr EntityVal;
387  if (IsEntityNm(EntityNm, EntityVal)){/*intentionaly empty*/}
388  else if (ChDef.IsEntityNm(EntityNm, EntityVal)){/*intentionaly empty*/}
389  else {EThrow(TStr("Entity-Reference (")+EntityNm+") does not exist.");}
390  return EntityVal;
391  } else {
392  EThrow("Invalid Entity-Reference."); Fail; return TStr();
393  }
394  }
395 }
396 
398  // [69] PEReference ::= '%' Name ';'
399  TStr EntityNm=GetName();
400  if ((EntityNm.Empty())||(Ch!=';')){EThrow("Invalid PEntity-Reference.");}
401  GetCh();
402  TStr EntityVal;
403  if (IsPEntityNm(EntityNm, EntityVal)){/*intentionaly empty*/}
404  else {EThrow(TStr("PEntity-Reference (")+EntityNm+") does not exist.");}
405  return EntityVal;
406 }
407 
409  // [25] Eq ::= S? '=' S?
410  GetWs(false);
411  if (Ch=='='){GetCh();}
412  else {EThrow("Equality ('=') character expected.");}
413  GetWs(false);
414 }
415 
417  // [5] Name ::= (Letter | '_' | ':') (NameChar)*
418  TChA NmChA;
419  if (ChDef.IsFirstNameCh(Ch)){
420  do {NmChA+=Ch;} while (ChDef.IsName(GetCh()));
421  } else {
422  EThrow("Invalid first name character.");
423  // EThrow(TStr::Fmt("Invalid first name character [%u:'%c%c%c%c%c'].",
424  // uint(Ch), Ch, RSIn.GetCh(), RSIn.GetCh(), RSIn.GetCh(), RSIn.GetCh()));
425  }
426  return NmChA;
427 }
428 
429 TStr TXmlLx::GetName(const TStr& RqNm){
430  TStr Nm=GetName();
431  // test if the name is equal to the required name
432  if (Nm==RqNm){return RqNm;}
433  else {EThrow(TStr("Name '")+RqNm+"' expected."); Fail; return TStr();}
434 }
435 
437  // [15] Comment ::= {{'<!-}}-' ((Char - '-') | ('-' (Char - '-')))* '-->'
438  if (GetCh()!='-'){EThrow("Invalid comment start.");}
439  TxtChA.Clr();
440  forever {
441  GetCh();
442  if (!ChDef.IsChar(Ch)){EThrow("Invalid comment character.");}
443  if (Ch=='-'){
444  if (GetCh()=='-'){
445  if (GetCh()=='>'){GetCh(); break;} // final bracket
446  else {EThrow("Invalid comment end.");}
447  } else {
448  if (!ChDef.IsChar(Ch)){EThrow("Invalid comment character.");}
449  TxtChA+='-'; TxtChA+=Ch; // special case if single '-'
450  }
451  } else {
452  TxtChA+=Ch; // usual char
453  }
454  }
455 }
456 
458  // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
459  // | "'" ([^<&'] | Reference)* "'"
460  uchar QCh=Ch;
461  if ((QCh!='"')&&(QCh!='\'')){EThrow("Invalid attribute-value start.");}
462  TChA ValChA; GetCh();
463  forever {
464  if ((Ch=='<')||(!ChDef.IsChar(Ch))){
465  EThrow("Invalid attribute-value character.");}
466  if (Ch==QCh){GetCh(); break;} // final quote
467  else if (Ch=='&'){GetCh(); ValChA+=GetReference();} // reference
468  else {ValChA+=Ch; GetCh();} // usual char
469  }
470  return ValChA;
471 }
472 
474  // [24] VersionInfo ::= {{S 'version' Eq}} (' VersionNum ' | " VersionNum ")
475  // [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
476  char QCh=Ch;
477  if ((Ch!='\'')&&(Ch!='"')){EThrow("Quote character (' or \") expected.");}
478  TChA VerNumChA;
479  GetCh();
480  do {
481  if ((('a'<=Ch)&&(Ch<='z'))||(('A'<=Ch)&&(Ch<='Z'))||
482  (('0'<=Ch)&&(Ch<='9'))||(Ch=='_')||(Ch=='.')||(Ch==':')||(Ch=='-')){
483  VerNumChA+=Ch;
484  } else {
485  EThrow("Invalid version-number character.");
486  }
487  GetCh();
488  } while (Ch!=QCh);
489  GetCh();
490  return VerNumChA;
491 }
492 
494  // [80] EncodingDecl ::= {{S 'encoding' Eq}} ('"' EncName '"' | "'" EncName "'" )
495  // [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
496  char QCh=Ch;
497  if ((Ch!='\'')&&(Ch!='"')){EThrow("Quote character (' or \") expected.");}
498  TChA EncNmChA;
499  GetCh();
500  if ((('a'<=Ch)&&(Ch<='z'))||(('A'<=Ch)&&(Ch<='Z'))){EncNmChA+=Ch;}
501  else {EThrow("Invalid encoding-name character.");}
502  GetCh();
503  while (Ch!=QCh){
504  if ((('a'<=Ch)&&(Ch<='z'))||(('A'<=Ch)&&(Ch<='Z'))||
505  (('0'<=Ch)&&(Ch<='9'))||(Ch=='.')||(Ch=='_')||(Ch=='-')){EncNmChA+=Ch;}
506  else {EThrow("Invalid version-number character.");}
507  GetCh();
508  }
509  GetCh();
510  return EncNmChA;
511 }
512 
514  // [32] SDDecl ::= {{S 'standalone' Eq}}
515  // (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))
516  char QCh=Ch;
517  if ((Ch!='\'')&&(Ch!='"')){EThrow("Quote character (' or \") expected.");}
518  TChA StalChA;
519  GetCh();
520  while (Ch!=QCh){
521  if (('a'<=Ch)&&(Ch<='z')){StalChA+=Ch;}
522  else {EThrow("Invalid standalone-value character.");}
523  GetCh();
524  }
525  GetCh();
526  TStr StalVal=StalChA;
527  if ((StalVal=="yes")||(StalVal=="no")){return StalVal;}
528  else {EThrow("Invalid standalone-value."); Fail; return TStr();}
529 }
530 
532  // [23] XMLDecl ::= {{'<?xml'}}... VersionInfo EncodingDecl? SDDecl? S? '?>'
533  // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
534  GetWs(true);
535  TStr VerNm=GetName("version"); GetEq(); TStr VerVal=GetVersionNum();
536  if (VerVal!="1.0"){EThrow("Invalid XML version.");}
537  AddArg(VerNm, VerVal);
538  GetWs(false);
539  if (Ch!='?'){
540  // EncodingDecl ::= {{S}} 'encoding' Eq
541  // ('"' EncName '"' | "'" EncName "'" )
542  TStr EncNm=GetName("encoding"); GetEq(); TStr EncVal=GetEncName();
543  AddArg(EncNm, EncVal);
544  }
545  GetWs(false);
546  if (Ch!='?'){
547  // SDDecl ::= {{S}} 'standalone' Eq
548  // (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))
549  TStr StalNm=GetName("standalone"); GetEq(); TStr StalVal=GetStalVal();
550  AddArg(StalNm, StalVal);
551  }
552  GetWs(false);
553  if (Ch=='?'){
554  GetCh();
555  if (Ch=='>'){GetCh();}
556  else {EThrow("Invalid end-of-tag in XML-declaration.");}
557  } else {
558  EThrow("Invalid end-of-tag in XML-declaration.");
559  }
560 }
561 
563  // [16] PI ::= {{'<?' PITarget}} (S (Char* - (Char* '?>' Char*)))? '?>'
564  // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
565  GetWs(false);
566  TxtChA.Clr();
567  forever {
568  if (!ChDef.IsChar(Ch)){EThrow("Invalid PI character.");}
569  if (Ch=='?'){
570  if (GetCh()=='>'){
571  GetCh(); break;
572  } else {
573  if (!ChDef.IsChar(Ch)){EThrow("Invalid PI character.");}
574  TxtChA+='?'; TxtChA+=Ch; // special case if single '?'
575  }
576  } else {
577  TxtChA+=Ch; // usual char
578  }
579  GetCh();
580  }
581 }
582 
584  // [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
585  char QCh=Ch;
586  if ((Ch!='\'')&&(Ch!='"')){EThrow("Quote character (' or \") expected.");}
587  TChA LitChA; GetCh();
588  while (Ch!=QCh){
589  if (!ChDef.IsChar(Ch)){EThrow("Invalid System-Literal character.");}
590  LitChA+=Ch; GetCh();
591  }
592  GetCh();
593  return LitChA;
594 }
595 
597  // [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
598  char QCh=Ch;
599  if ((Ch!='\'')&&(Ch!='"')){EThrow("Quote character (' or \") expected.");}
600  TChA LitChA; GetCh();
601  while (Ch!=QCh){
602  if (!ChDef.IsPubid(Ch)){EThrow("Invalid Public-Id-Literal character.");}
603  LitChA+=Ch; GetCh();
604  }
605  GetCh();
606  return LitChA;
607 }
608 
610  // ExternalID ::= 'SYSTEM' S SystemLiteral
611  // | 'PUBLIC' S PubidLiteral S SystemLiteral
612  TStr ExtIdNm=GetName();
613  if (ExtIdNm=="SYSTEM"){
614  GetWs(true); GetSystemLiteral();
615  } else if (ExtIdNm=="PUBLIC"){
616  GetWs(true); GetPubidLiteral(); GetWs(true); GetSystemLiteral();
617  } else {
618  EThrow("Invalid external-id ('SYSTEM' or 'PUBLIC' expected).");
619  }
620 }
621 
623  // [76] NDataDecl ::= S 'NDATA' S Name
624  GetName("NDATA"); GetWs(true); GetName();
625 }
626 
628  // [28] doctypedecl ::= {{'<!DOCTYPE'}} S Name (S ExternalID)? S?
629  // ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
630  GetWs(true);
631  TStr DocTypeDeclNm=GetName();
632  GetWs(false);
633  if (Ch=='>'){GetCh(); return;}
634  if (Ch!='['){GetExternalId();}
635  GetWs(false);
636  if (Ch=='['){
637  GetCh();
638  // [28] (markupdecl | PEReference | S)*
639  GetWs(false);
640  while (Ch!=']'){
641  if (ChDef.IsWs(Ch)){GetWs(true);}
642  else if (Ch=='%'){GetPEReference();}
643  else {
644  GetSym();
645  }
646  }
647  GetCh();
648  }
649  GetWs(false);
650  // '>'
651  if (Ch=='>'){GetCh();}
652  else {EThrow("Invalid end-of-tag in document-type-declaration.");}
653  TagNm=DocTypeDeclNm;
654 }
655 
657  TxtChA.Clr();
658  while (Ch!='>'){
659  if (!ChDef.IsChar(Ch)){EThrow("Invalid Element character.");}
660  TxtChA+=Ch; GetCh();
661  }
662  GetCh();
663 }
664 
666  TxtChA.Clr();
667  while (Ch!='>'){
668  if (!ChDef.IsChar(Ch)){EThrow("Invalid Element character.");}
669  TxtChA+=Ch; GetCh();
670  }
671  GetCh();
672 }
673 
675  // [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
676  // | "'" ([^%&'] | PEReference | Reference)* "'"
677  uchar QCh=Ch;
678  if ((QCh!='"')&&(QCh!='\'')){EThrow("Invalid entity-value start.");}
679  TChA ValChA; GetCh();
680  forever {
681  if (!ChDef.IsChar(Ch)){EThrow("Invalid entity-value character.");}
682  if (Ch==QCh){GetCh(); break;} // final quote
683  else if (Ch=='&'){GetCh(); ValChA+=GetReference();} // reference
684  else if (Ch=='%'){GetCh(); ValChA+=GetPEReference();} // pereference
685  else {ValChA+=Ch; GetCh();} // usual char
686  }
687  return ValChA;
688 }
689 
691  // [70] EntityDecl ::= GEDecl | PEDecl
692  // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
693  // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
694  GetWs(true); TStr EntityNm;
695  if (Ch=='%'){
696  GetCh(); GetWs(true); EntityNm=GetName(); GetWs(true);
697  // [74] PEDef ::= EntityValue | ExternalID
698  if ((Ch=='\"')||(Ch=='\'')){
699  TStr EntityVal=GetEntityValue();
700  PutPEntityVal(EntityNm, EntityVal);
701  } else {
702  GetExternalId();
703  GetWs(false);
704  if (Ch!='>'){GetNData();}
705  }
706  } else {
707  EntityNm=GetName(); GetWs(true);
708  // [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
709  if ((Ch=='\"')||(Ch=='\'')){
710  TStr EntityVal=GetEntityValue();
711  PutEntityVal(EntityNm, EntityVal);
712  } else {
713  GetExternalId();
714  }
715  }
716  GetWs(false);
717  if (Ch=='>'){GetCh();}
718  else {EThrow("Invalid end-of-tag in entity-declaration.");}
719  TagNm=EntityNm;
720 }
721 
723  // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
724  // [83] PublicID ::= 'PUBLIC' S PubidLiteral
725  TxtChA.Clr();
726  while (Ch!='>'){
727  if (!ChDef.IsChar(Ch)){EThrow("Invalid Element character.");}
728  TxtChA+=Ch; GetCh();
729  }
730  GetCh();
731 }
732 
734  // [18] CDSect ::= CDStart CData CDEnd
735  // [19] CDStart ::= '<![CDATA{{['}}
736  // [20] CData ::= (Char* - (Char* ']]>' Char*))
737  // [21] CDEnd ::= ']]>'
738  if (Ch=='['){GetCh();}
739  else {EThrow("Invalid start of CDATA section.");}
740  TxtChA.Clr();
741  forever {
742  if (!ChDef.IsChar(Ch)){EThrow("Invalid CDATA character.");}
743  if ((Ch=='>')&&(TxtChA.Len()>=2)&&
744  (TxtChA.LastLastCh()==']') && (TxtChA.LastCh()==']')){
745  GetCh(); TxtChA.Pop(); TxtChA.Pop(); break;
746  } else {
747  TxtChA+=Ch; GetCh();
748  }
749  }
750 }
751 
753  // [3] S ::= (#x20 | #x9 | #xD | #xA)+
754  while (ChDef.IsWs(Ch)){GetCh();}
755 }
756 
758  if (Ch=='<'){
759  GetCh(); ClrArgV();
760  if (Ch=='?'){
761  GetCh(); TagNm=GetName();
762  if (TagNm.GetLc()=="xml"){Sym=xsyXmlDecl; GetXmlDecl();}
763  else {Sym=xsyPI; GetPI();}
764  } else
765  if (Ch=='!'){
766  GetCh();
767  if (Ch=='['){
768  GetCh(); TagNm=GetName();
769  if (TagNm=="CDATA"){Sym=xsyQStr; GetCDSect();}
770  else {EThrow(TStr("Invalid tag after '<![' (")+TagNm+").");}
771  } else
772  if (Ch=='-'){
774  } else {
775  TagNm=GetName();
776  if (TagNm=="DOCTYPE"){GetDocTypeDecl(); Sym=xsyDocTypeDecl;}
777  else if (TagNm=="ELEMENT"){GetElement(); Sym=xsyElement;}
778  else if (TagNm=="ATTLIST"){GetAttList(); Sym=xsyAttList;}
779  else if (TagNm=="ENTITY"){GetEntity(); Sym=xsyEntity;}
780  else if (TagNm=="NOTATION"){GetNotation(); Sym=xsyNotation;}
781  else {EThrow(TStr("Invalid tag (")+TagNm+").");}
782  }
783  } else
784  if (Ch=='/'){
785  // xsyETag
786  GetCh(); Sym=xsyETag; TagNm=GetName(); GetWs(false);
787  if (Ch=='>'){GetCh();}
788  else {EThrow("Invalid End-Tag.");}
789  } else {
790  // xsySTag or xsySETag
791  TagNm=GetName(); GetWs(false);
792  while ((Ch!='>')&&(Ch!='/')){
793  TStr AttrNm=GetName();
794  GetEq();
795  TStr AttrVal=GetAttValue();
796  GetWs(false);
797  AddArg(AttrNm, AttrVal);
798  }
799  if (Ch=='/'){
800  if (GetCh()=='>'){Sym=xsySETag; GetCh();}
801  else {EThrow("Invalid Empty-Element-Tag.");}
802  } else {
803  Sym=xsySTag; GetCh();
804  }
805  }
806  if (Spacing==xspTruncate){SkipWs();}
807  } else
808  if (ChDef.IsWs(Ch)){
809  Sym=xsyWs; GetWs(true); ToNrSpacing();
810  if (Spacing==xspTruncate){GetSym();}
811  } else
812  if (Ch==TCh::EofCh){
813  Sym=xsyEof;
814  } else {
815  Sym=xsyStr; TxtChA.Clr();
816  // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
817  forever {
818  if (!ChDef.IsChar(Ch)){
819  EThrow(TUInt::GetStr(Ch, "Invalid character (%d)."));}
820  // GetCh(); continue; // skip invalid characters
821  if (Ch=='<'){break;} // tag
822  if (Ch=='&'){GetCh(); TxtChA+=GetReference();} // reference
823  else {
824  if ((Ch=='>')&&(TxtChA.Len()>=2)&&
825  (TxtChA.LastLastCh()==']')&&(TxtChA.LastCh()==']')){
826  EThrow("Forbidden substring ']]>' in character data.");}
827  TxtChA+=Ch; GetCh(); // usual char
828  }
829  }
830  ToNrSpacing();
831  }
832  return Sym;
833 }
834 
836  TChA SymChA;
837  switch (Sym){
838  case xsyUndef:
839  SymChA="{Undef}"; break;
840  case xsyWs:
841  SymChA+="{Space:'"; SymChA+=TStr(TxtChA).GetHex(); SymChA+="'}"; break;
842  case xsyComment:
843  SymChA+="<!--"; SymChA+=TxtChA; SymChA+="-->"; break;
844  case xsyXmlDecl:{
845  SymChA+="<?"; SymChA+=TagNm;
846  for (int ArgN=0; ArgN<GetArgs(); ArgN++){
847  TStr ArgNm; TStr ArgVal; GetArg(ArgN, ArgNm, ArgVal);
848  char ArgValQCh=GetArgValQCh(ArgVal);
849  SymChA+=' '; SymChA+=ArgNm; SymChA+='=';
850  SymChA+=ArgValQCh; SymChA+=ArgVal; SymChA+=ArgValQCh;
851  }
852  SymChA+="?>"; break;}
853  case xsyPI:
854  SymChA+="<?"; SymChA+=TagNm;
855  if (!TxtChA.Empty()){SymChA+=' '; SymChA+=TxtChA;}
856  SymChA+="?>"; break;
857  case xsyDocTypeDecl:
858  SymChA+="<!DOCTYPE "; SymChA+=TagNm; SymChA+=">"; break;
859  case xsySTag:
860  case xsySETag:{
861  SymChA+="<"; SymChA+=TagNm;
862  for (int ArgN=0; ArgN<GetArgs(); ArgN++){
863  TStr ArgNm; TStr ArgVal; GetArg(ArgN, ArgNm, ArgVal);
864  char ArgValQCh=GetArgValQCh(ArgVal);
865  SymChA+=' '; SymChA+=ArgNm; SymChA+='=';
866  SymChA+=ArgValQCh; SymChA+=ArgVal; SymChA+=ArgValQCh;
867  }
868  if (Sym==xsySTag){SymChA+=">";}
869  else if (Sym==xsySETag){SymChA+="/>";}
870  else {Fail;}
871  break;}
872  case xsyETag:
873  SymChA+="</"; SymChA+=TagNm; SymChA+=">"; break;
874  case xsyStr:
875  SymChA="{String:'"; SymChA+=TxtChA; SymChA+="'}"; break;
876  case xsyQStr:
877  SymChA="{QString:'"; SymChA+=TxtChA; SymChA+="'}"; break;
878  case xsyEof:
879  SymChA="{Eof}"; break;
880  default: Fail;
881  }
882  return SymChA;
883 }
884 
885 void TXmlLx::EThrow(const TStr& MsgStr) const {
886  TChA FPosChA;
887  FPosChA+=" [File:"; FPosChA+=SIn->GetSNm();
888  FPosChA+=" Line:"; FPosChA+=TInt::GetStr(LnN);
889  FPosChA+=" Char:"; FPosChA+=TInt::GetStr(LnChN);
890  FPosChA+="]";
891  TStr FullMsgStr=MsgStr+FPosChA;
892  TExcept::Throw(FullMsgStr);
893 }
894 
896  TChA FPosChA;
897  FPosChA+=" [File:"; FPosChA+=SIn->GetSNm();
898  FPosChA+=" Line:"; FPosChA+=TInt::GetStr(LnN);
899  FPosChA+=" Char:"; FPosChA+=TInt::GetStr(LnChN);
900  FPosChA+="]";
901  return FPosChA;
902 }
903 
905  switch (XmlLxSym){
906  case xsyUndef: return "Undef";
907  case xsyWs: return "White-Space";
908  case xsyComment: return "Comment";
909  case xsyXmlDecl: return "Declaration";
910  case xsyPI: return "PI";
911  case xsyDocTypeDecl: return "Document-Type";
912  case xsyElement: return "Element";
913  case xsyAttList: return "Attribute-List";
914  case xsyEntity: return "Entity";
915  case xsyNotation: return "Notation";
916  case xsyTag: return "Tag";
917  case xsySTag: return "Start-Tag";
918  case xsyETag: return "End-Tag";
919  case xsySETag: return "Start-End-Tag";
920  case xsyStr: return "String";
921  case xsyQStr: return "Quoted-String";
922  case xsyEof: return "Eon-Of-File";
923  default: return "Undef";
924  }
925 }
926 
927 bool TXmlLx::IsTagNm(const TStr& Str){
928  TChA ChA=Str;
929  if (ChA.Len()>0){
930  if (TXmlLx::ChDef.IsFirstNameCh(ChA[0])){
931  for (int ChN=1; ChN<ChA.Len(); ChN++){
932  if (!TXmlLx::ChDef.IsName(ChA[ChN])){
933  return false;
934  }
935  }
936  return true;
937  } else {
938  return false;
939  }
940  } else {
941  return false;
942  }
943 }
944 
946  TChA XmlChA;
947  for (int ChN=0; ChN<PlainMem.Len(); ChN++){
948  uchar Ch=PlainMem[ChN];
949  if ((' '<=Ch)&&(Ch<='~')){
950  switch (Ch){
951  case '"': XmlChA+="&quot;"; break;
952  case '&': XmlChA+="&amp;"; break;
953  case '\'': XmlChA+="&apos;"; break;
954  case '<': XmlChA+="&lt;"; break;
955  case '>': XmlChA+="&gt;"; break;
956  default: XmlChA+=Ch;
957  }
958  } else
959  if ((Ch=='\r')||(Ch=='\n')){
960  XmlChA+=Ch;
961  } else {
962  XmlChA+='&'; XmlChA+='#'; XmlChA+=TUInt::GetStr(Ch); XmlChA+=';';
963  }
964  }
965  return XmlChA;
966 }
967 
969  TChA XmlChA;
970  for (int ChN=0; ChN<PlainChA.Len(); ChN++){
971  uchar Ch=PlainChA[ChN];
972  if ((' '<=Ch)&&(Ch<='~')){
973  switch (Ch){
974  case '"': XmlChA+="&quot;"; break;
975  case '&': XmlChA+="&amp;"; break;
976  case '\'': XmlChA+="&apos;"; break;
977  case '<': XmlChA+="&lt;"; break;
978  case '>': XmlChA+="&gt;"; break;
979  default: XmlChA+=Ch;
980  }
981  } else
982  if ((Ch=='\r')||(Ch=='\n')){
983  XmlChA+=Ch;
984  } else {
985  XmlChA+='&'; XmlChA+='#'; XmlChA+=TUInt::GetStr(Ch); XmlChA+=';';
986  }
987  }
988  return XmlChA;
989 }
990 
992  TChA PlainChA;
993  TChRet Ch(TStrIn::New(XmlStr));
994  Ch.GetCh();
995  while (!Ch.Eof()){
996  if (Ch()!='&'){
997  PlainChA+=Ch(); Ch.GetCh();
998  } else {
999  // [67] Reference ::= EntityRef | CharRef
1000  if (Ch.GetCh()=='#'){
1001  // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
1002  TChA RefChA; int RefCd=0;
1003  if (Ch.GetCh()=='x'){
1004  // hex-decimal character code
1005  forever {
1006  Ch.GetCh();
1007  if (TCh::IsHex(Ch())){
1008  RefChA+=Ch();
1009  RefCd=RefCd*16+TCh::GetHex(Ch());
1010  } else {
1011  break;
1012  }
1013  }
1014  } else {
1015  // decimal character code
1016  forever {
1017  if (TCh::IsNum(Ch())){
1018  RefChA+=Ch();
1019  RefCd=RefCd*10+TCh::GetNum(Ch());
1020  } else {
1021  break;
1022  }
1023  Ch.GetCh();
1024  }
1025  }
1026  if ((!RefChA.Empty())&&(Ch()==';')){
1027  Ch.GetCh();
1028  if (RefCd < 0x80) {
1029  // ascii character
1030  uchar RefCh=uchar(RefCd);
1031  PlainChA+=RefCh;
1032  } else {
1033  // unicode
1034  TUnicode::EncodeUtf8(RefCd, PlainChA);
1035  }
1036  }
1037  } else {
1038  // [68] EntityRef ::= '&' Name ';'
1039  TChA EntityNm;
1040  while ((!Ch.Eof())&&(Ch()!=';')){
1041  EntityNm+=Ch(); Ch.GetCh();}
1042  if ((!EntityNm.Empty())&&(Ch()==';')){
1043  Ch.GetCh();
1044  if (EntityNm=="quot"){PlainChA+='"';}
1045  else if (EntityNm=="amp"){PlainChA+='&';}
1046  else if (EntityNm=="apos"){PlainChA+='\'';}
1047  else if (EntityNm=="lt"){PlainChA+='<';}
1048  else if (EntityNm=="gt"){PlainChA+='>';}
1049  }
1050  }
1051  }
1052  }
1053  return PlainChA;
1054 }
1055 
1057  TStr UsAsciiStr=XmlStr;
1058  UsAsciiStr.ChangeStrAll("&#232;", "c");
1059  UsAsciiStr.ChangeStrAll("&#200;", "C");
1060  UsAsciiStr.ChangeStrAll("&#154;", "s");
1061  UsAsciiStr.ChangeStrAll("&#138;", "S");
1062  UsAsciiStr.ChangeStrAll("&#158;", "z");
1063  UsAsciiStr.ChangeStrAll("&#142;", "Z");
1064  TChA UsAsciiChA=TXmlLx::GetPlainStrFromXmlStr(UsAsciiStr);
1065  for (int ChN=0; ChN<UsAsciiChA.Len(); ChN++){
1066  char Ch=UsAsciiChA[ChN];
1067  if ((Ch<' ')||('~'<Ch)){UsAsciiChA.PutCh(ChN, 'x');}
1068  }
1069  return UsAsciiChA;
1070 }
1071 
1073  TStr ChRefStr=YuEntRefStr;
1074  ChRefStr.ChangeStrAll("&ch;", "&#232;");
1075  ChRefStr.ChangeStrAll("&Ch;", "&#200;");
1076  ChRefStr.ChangeStrAll("&sh;", "&#154;");
1077  ChRefStr.ChangeStrAll("&Sh;", "&#138;");
1078  ChRefStr.ChangeStrAll("&zh;", "&#158;");
1079  ChRefStr.ChangeStrAll("&Zh;", "&#142;");
1080  ChRefStr.ChangeStrAll("&cs", "c");
1081  ChRefStr.ChangeStrAll("&Cs;", "C");
1082  ChRefStr.ChangeStrAll("&dz;", "dz");
1083  ChRefStr.ChangeStrAll("&Dz;", "Dz");
1084  return ChRefStr;
1085 }
1086 
1088 // Xml-Token
1089 bool TXmlTok::GetBoolArgVal(const TStr& ArgNm, const bool& DfVal) const {
1090  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1091  return (ArgN==-1) ? DfVal : (ArgNmValV[ArgN].Dat==TBool::TrueStr);
1092 }
1093 
1095  const TStr& ArgNm, const TStr& TrueVal, const bool& DfVal) const {
1096  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1097  return (ArgN==-1) ? DfVal : (ArgNmValV[ArgN].Dat==TrueVal);
1098 }
1099 
1100 bool TXmlTok::GetBoolArgVal(const TStr& ArgNm,
1101  const TStr& TrueVal, const TStr& FalseVal, const bool& DfVal) const {
1102  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1103  if (ArgN==-1){return DfVal;}
1104  TStr ArgVal=ArgNmValV[ArgN].Dat;
1105  if (ArgVal==TrueVal){return true;}
1106  IAssert(ArgVal == FalseVal); return false;
1107 }
1108 
1109 int TXmlTok::GetIntArgVal(const TStr& ArgNm, const int& DfVal) const {
1110  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1111  if (ArgN==-1){
1112  return DfVal;
1113  } else {
1114  int Val;
1115  if (ArgNmValV[ArgN].Dat.IsInt(Val)){return Val;} else {return DfVal;}
1116  }
1117 }
1118 
1119 double TXmlTok::GetFltArgVal(const TStr& ArgNm, const double& DfVal) const {
1120  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1121  if (ArgN==-1){
1122  return DfVal;
1123  } else {
1124  double Val;
1125  if (ArgNmValV[ArgN].Dat.IsFlt(Val)){return Val;} else {return DfVal;}
1126  }
1127 }
1128 
1129 TStr TXmlTok::GetStrArgVal(const TStr& ArgNm, const TStr& DfVal) const {
1130  int ArgN=ArgNmValV.SearchForw(TStrKd(ArgNm));
1131  return (ArgN==-1) ? DfVal : ArgNmValV[ArgN].Dat;
1132 }
1133 
1134 void TXmlTok::PutSubTok(const PXmlTok& Tok, const int& SubTokN){
1135  if (SubTokN==-1){
1136  ClrSubTok(); AddSubTok(Tok);
1137  } else {
1138  SubTokV[SubTokN]=Tok;
1139  }
1140 }
1141 
1142 PXmlTok TXmlTok::GetTagTok(const TStr& TagPath) const {
1143  if (TagPath.Empty()){
1144  return (TXmlTok*)this;
1145  } else {
1146  TStr TagNm; TStr RestTagPath; TagPath.SplitOnCh(TagNm, '|', RestTagPath);
1147  PXmlTok SubTok;
1148  for (int SubTokN=0; SubTokN<SubTokV.Len(); SubTokN++){
1149  SubTok=SubTokV[SubTokN];
1150  if ((SubTok->GetSym()==xsyTag)&&(SubTok->GetStr()==TagNm)){break;}
1151  else {SubTok=NULL;}
1152  }
1153  if ((SubTok.Empty())||(RestTagPath.Empty())){return SubTok;}
1154  else {return SubTok->GetTagTok(RestTagPath);}
1155  }
1156 }
1157 
1158 void TXmlTok::GetTagTokV(const TStr& TagPath, TXmlTokV& XmlTokV) const {
1159  XmlTokV.Clr();
1160  TStr PreTagPath; TStr TagNm; TagPath.SplitOnLastCh(PreTagPath, '|', TagNm);
1161  PXmlTok Tok=GetTagTok(PreTagPath);
1162  if (!Tok.Empty()){
1163  for (int SubTokN=0; SubTokN<Tok->GetSubToks(); SubTokN++){
1164  PXmlTok SubTok=Tok->GetSubTok(SubTokN);
1165  if ((SubTok->GetSym()==xsyTag)&&(SubTok->GetStr()==TagNm)){
1166  XmlTokV.Add(SubTok);}
1167  }
1168  }
1169 }
1170 
1171 void TXmlTok::GetTagValV(const TStr& TagNm, const bool& XmlP, TStrV& ValV) const {
1172  if ((Sym==xsyTag)&&(Str==TagNm)){
1173  ValV.Add(GetTokStr(XmlP));
1174  } else {
1175  for (int SubTokN=0; SubTokN<GetSubToks(); SubTokN++){
1176  GetSubTok(SubTokN)->GetTagValV(TagNm, XmlP, ValV);}
1177  }
1178 }
1179 
1180 TStr TXmlTok::GetTagVal(const TStr& TagNm, const bool& XmlP) const {
1181  TStrV ValV; GetTagValV(TagNm, XmlP, ValV);
1182  if (ValV.Len()>0){return ValV[0];} else {return "";}
1183 }
1184 
1185 void TXmlTok::AddTokToChA(const bool& XmlP, TChA& ChA) const {
1186  switch (Sym){
1187  case xsyWs:
1188  ChA+=Str; break;
1189  case xsyStr:
1190  if (XmlP){ChA+=TXmlLx::GetXmlStrFromPlainStr(Str);} else {ChA+=Str;} break;
1191  case xsyQStr:
1192  if (XmlP){ChA+="<![CDATA[";}
1193  ChA+=Str;
1194  if (XmlP){ChA+="]]>";} break;
1195  case xsyTag:
1196  if (XmlP){
1197  ChA+='<'; ChA+=Str;
1198  for (int ArgN=0; ArgN<GetArgs(); ArgN++){
1199  TStr ArgNm; TStr ArgVal; GetArg(ArgN, ArgNm, ArgVal);
1200  if (XmlP){ArgVal=TXmlLx::GetXmlStrFromPlainStr(ArgVal);}
1201  char ArgValQCh=TXmlLx::GetArgValQCh(ArgVal);
1202  ChA+=' '; ChA+=ArgNm; ChA+='=';
1203  ChA+=ArgValQCh; ChA+=ArgVal; ChA+=ArgValQCh;
1204  }
1205  }
1206  if (GetSubToks()==0){
1207  if (XmlP){ChA+="/>";}
1208  } else {
1209  if (XmlP){ChA+=">";}
1210  for (int SubTokN=0; SubTokN<GetSubToks(); SubTokN++){
1211  GetSubTok(SubTokN)->AddTokToChA(XmlP, ChA);}
1212  if (XmlP){ChA+="</"; ChA+=Str; ChA+='>';}
1213  }
1214  break;
1215  default: Fail;
1216  }
1217 }
1218 
1219 TStr TXmlTok::GetTokVStr(const TXmlTokV& TokV, const bool& XmlP){
1220  TChA TokVChA;
1221  for (int TokN=0; TokN<TokV.Len(); TokN++){
1222  if (TokN>0){TokVChA+=' ';}
1223  TokVChA+=TokV[TokN]->GetTokStr(XmlP);
1224  }
1225  return TokVChA;
1226 }
1227 
1229  switch (Lx.Sym){
1230  case xsyWs:
1231  case xsyStr:
1232  case xsyQStr:
1233  return TXmlTok::New(Lx.Sym, Lx.TxtChA);
1234  case xsySTag:
1235  case xsySETag:
1236  return TXmlTok::New(xsyTag, Lx.TagNm, Lx.ArgNmValKdV);
1237  default: Fail; return NULL;
1238  }
1239 }
1240 
1242 // Xml-Document
1244  // [27] Misc ::= Comment | PI | S
1245  while ((Lx.Sym==xsyComment)||(Lx.Sym==xsyPI)||(Lx.Sym==xsyWs)){
1246  Lx.GetSym();}
1247 }
1248 
1250  // [39] element ::= EmptyElemTag | STag content ETag
1251  PXmlTok Tok;
1252  if (Lx.Sym==xsySETag){
1253  Tok=TXmlTok::GetTok(Lx);
1254  } else
1255  if (Lx.Sym==xsySTag){
1256  Tok=TXmlTok::GetTok(Lx);
1257  forever {
1258  Lx.GetSym();
1259  if (Lx.Sym==xsyETag){
1260  if (Tok->GetStr()==Lx.TagNm){
1261  break;
1262  } else {
1263  TStr MsgStr=TStr("Invalid End-Tag '")+Lx.TagNm+
1264  "' ('"+Tok->GetStr()+"' expected).";
1265  Lx.EThrow(MsgStr);
1266  }
1267  } else {
1268  PXmlTok SubTok;
1269  switch (Lx.Sym){
1270  case xsySTag:
1271  SubTok=LoadTxtElement(Lx); break;
1272  case xsySETag:
1273  case xsyStr:
1274  case xsyQStr:
1275  case xsyWs:
1276  SubTok=TXmlTok::GetTok(Lx); break;
1277  case xsyPI:
1278  case xsyComment:
1279  break;
1280  default: Lx.EThrow("Content or End-Tag expected.");
1281  }
1282  if (!SubTok.Empty()){
1283  Tok->AddSubTok(SubTok);}
1284  }
1285  }
1286  } else
1287  if (Lx.Sym==xsyETag){
1288  TStr MsgStr=
1289  TStr("Xml-Element (Start-Tag or Empty-Element-Tag) required.")+
1290  TStr::GetStr(Lx.TagNm, " End-Tag </%s> encountered.");
1291  Lx.EThrow(MsgStr);
1292  } else {
1293  Lx.EThrow("Xml-Element (Start-Tag or Empty-Element-Tag) required.");
1294  }
1295  return Tok;
1296 }
1297 
1298 PXmlTok TXmlDoc::GetTagTok(const TStr& TagPath) const {
1299  if (TagPath.Empty()){
1300  return Tok;
1301  } else {
1302  TStr TagNm; TStr RestTagPath; TagPath.SplitOnCh(TagNm, '|', RestTagPath);
1303  if ((Tok->GetSym()==xsyTag)&&(Tok->GetStr()==TagNm)){
1304  if (RestTagPath.Empty()){return Tok;}
1305  else {return Tok->GetTagTok(RestTagPath);}
1306  } else {
1307  return NULL;
1308  }
1309  }
1310 }
1311 
1312 void TXmlDoc::PutTagTokStr(const TStr& TagPath, const TStr& TokStr) const {
1313  PXmlTok Tok=GetTagTok(TagPath);
1314  Tok->ClrSubTok();
1315  PXmlTok StrTok=TXmlTok::New(xsyStr, TokStr);
1316  Tok->AddSubTok(StrTok);
1317 }
1318 
1319 void TXmlDoc::GetTagTokV(const TStr& TagPath, TXmlTokV& XmlTokV) const {
1320  XmlTokV.Clr();
1321  TStr PreTagPath; TStr TagNm; TagPath.SplitOnLastCh(PreTagPath, '|', TagNm);
1322  PXmlTok Tok=GetTagTok(PreTagPath);
1323  if (!Tok.Empty()){
1324  for (int SubTokN=0; SubTokN<Tok->GetSubToks(); SubTokN++){
1325  PXmlTok SubTok=Tok->GetSubTok(SubTokN);
1326  if ((SubTok->GetSym()==xsyTag)&&(SubTok->GetStr()==TagNm)){
1327  XmlTokV.Add(SubTok);}
1328  }
1329  }
1330 }
1331 
1333  const TStr& TagPath, const TStr& ArgNm, const bool& DfVal) const {
1334  PXmlTok TagTok;
1335  if (IsTagTok(TagPath, TagTok)){
1336  return TagTok->GetBoolArgVal(ArgNm, DfVal);}
1337  else {return DfVal;}
1338 }
1339 
1341  const TStr& TagPath, const TStr& ArgNm, const int& DfVal) const {
1342  PXmlTok TagTok;
1343  if (IsTagTok(TagPath, TagTok)){
1344  return TagTok->GetIntArgVal(ArgNm, DfVal);}
1345  else {return DfVal;}
1346 }
1347 
1349  const TStr& TagPath, const TStr& ArgNm, const double& DfVal) const {
1350  PXmlTok TagTok;
1351  if (IsTagTok(TagPath, TagTok)){
1352  return TagTok->GetFltArgVal(ArgNm, DfVal);}
1353  else {return DfVal;}
1354 }
1355 
1357  const TStr& TagPath, const TStr& ArgNm, const TStr& DfVal) const {
1358  PXmlTok TagTok;
1359  if (IsTagTok(TagPath, TagTok)){
1360  return TagTok->GetStrArgVal(ArgNm, DfVal);}
1361  else {return DfVal;}
1362 }
1363 
1365  TChA ChA=Str;
1366  TChA XmlChA;
1367  for (int ChN=0; ChN<ChA.Len(); ChN++){
1368  uchar Ch=ChA[ChN];
1369  if ((' '<=Ch)&&(Ch<='~')){
1370  if (Ch=='&'){XmlChA+="&amp;";}
1371  else if (Ch=='>'){XmlChA+="&lt;";}
1372  else if (Ch=='<'){XmlChA+="&gt;";}
1373  else if (Ch=='\''){XmlChA+="&apos;";}
1374  else if (Ch=='\"'){XmlChA+="&quot;";}
1375  else {XmlChA+=Ch;}
1376  } else {
1377  XmlChA+="&#"; XmlChA+=TUInt::GetStr(Ch); XmlChA+=";";
1378  }
1379  }
1380  return XmlChA;
1381 }
1382 
1383 bool TXmlDoc::SkipTopTag(const PSIn& SIn){
1384  bool Ok=true;
1385  TXmlLx Lx(SIn, xspIntact);
1386  try {
1387  Lx.GetSym();
1388  // [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
1389  if (Lx.Sym==xsyXmlDecl){Lx.GetSym();}
1390  LoadTxtMiscStar(Lx);
1391  if (Lx.Sym==xsyDocTypeDecl){Lx.GetSym();}
1392  LoadTxtMiscStar(Lx);
1393  Ok=true;
1394  }
1395  catch (PExcept Except){
1396  Ok=false;
1397  }
1398  return Ok;
1399 }
1400 
1402  PXmlDoc Doc=TXmlDoc::New();
1403  // [1] document ::= prolog element Misc*
1404  try {
1405  Lx.GetSym();
1406  // [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
1407  if (Lx.Sym==xsyXmlDecl){Lx.GetSym();}
1408  LoadTxtMiscStar(Lx);
1409  if (Lx.Sym==xsyDocTypeDecl){Lx.GetSym();}
1410  LoadTxtMiscStar(Lx);
1411  Doc->Tok=LoadTxtElement(Lx);
1412  LoadTxtMiscStar(Lx);
1413  Doc->Ok=true; Doc->MsgStr="Ok";
1414  }
1415  catch (PExcept& Except){
1416  Doc->Ok=false; Doc->MsgStr=Except->GetMsgStr();
1417  }
1418  return Doc;
1419 }
1420 
1421 PXmlDoc TXmlDoc::LoadTxt(const PSIn& SIn, const TXmlSpacing& Spacing){
1422  TXmlLx Lx(SIn, Spacing); return LoadTxt(Lx);
1423 }
1424 
1425 PXmlDoc TXmlDoc::LoadTxt(const TStr& FNm, const TXmlSpacing& Spacing){
1426  PSIn SIn=TFIn::New(FNm); return LoadTxt(SIn, Spacing);
1427 }
1428 
1430  const TStr& FNm, TXmlDocV& XmlDocV, const TXmlSpacing& Spacing){
1431  XmlDocV.Clr();
1432  PSIn SIn=TFIn::New(FNm);
1433  TXmlLx Lx(SIn, Spacing);
1434  PXmlDoc XmlDoc;
1435  forever {
1436  Lx.SkipWs();
1437  XmlDoc=LoadTxt(Lx);
1438  if (XmlDoc->IsOk()){XmlDocV.Add(XmlDoc);}
1439  else {break;}
1440  }
1441 }
1442 
1444  PSIn SIn=TStrIn::New(Str);
1445  return LoadTxt(SIn);
1446 }
1447 
1449  PSOut SOut=TMOut::New(); TMOut& MOut=*(TMOut*)SOut();
1450  SaveTxt(SOut);
1451  Str=MOut.GetAsStr();
1452 }
1453 
1455 // Fast and dirty XML parser
1456 // very basic it does only <item>string</item>, no comments, no arguments
1458  if (NextSym != xsyUndef) {
1461  return Sym;
1462  }
1463  SymStr.Clr();
1464  char Ch;
1465  while (TCh::IsWs(Ch=GetCh())) { }
1466  if (Ch == TCh::EofCh) { Sym = xsyEof; return xsyEof; }
1467  if (Ch == '<') { // load tag
1468  Ch = GetCh();
1469  if (Ch == '/') { Sym = xsyETag; }
1470  else { Sym = xsySTag; SymStr.Push(Ch); }
1471  while((Ch=GetCh())!='>' && Ch!=TCh::EofCh) { SymStr.Push(Ch); }
1472  const int StrLen = SymStr.Len();
1473  if (StrLen > 1 && SymStr[StrLen-1] == '/') {
1474  Sym = xsyETag; SymStr[StrLen-1] = 0;
1475  for (char *c = SymStr.CStr()+StrLen-2; TCh::IsWs(*c); c--) { *c=0; }
1476  }
1477  } else { // load string
1478  _SymStr.Clr(); _SymStr.Push(Ch);
1479  while (! RSIn.Eof() && RSIn.PeekCh() != '<') { _SymStr.Push(GetCh()); }
1481  Sym = xsyStr;
1482  }
1483  if (Ch == TCh::EofCh) { SymStr.Clr(); Sym = xsyEof; return xsyEof; }
1484  return Sym;
1485 }
1486 
1488  GetSym();
1489  _SymStr = SymStr;
1490  return Sym;
1491 }
1492 
1494  if (NextSym == xsyUndef) {
1495  const TXmlLxSym TmpSim=Sym;
1496  const TChA TmpSymStr=SymStr;
1498  Sym=TmpSim;
1499  SymStr=TmpSymStr;
1500  }
1501  return NextSym;
1502 }
1503 
1505  PeekSym();
1506  _SymStr = NextSymStr;
1507  return NextSym;
1508 }
1509 
1510 void TXmlParser::SkipTillTag(const TChA& _SymStr) {
1511  while(PeekSym() != xsyEof) {
1512  if (NextSymStr == _SymStr) { return; }
1513  GetSym();
1514  }
1515 }
1516 
1517 // get <tag>value</tag>
1518 void TXmlParser::GetTagVal(const TChA& TagStr, TChA& TagVal) {
1519  EAssertR(GetTag(TagStr) == xsySTag, TStr::Fmt("Expected '<%s>'. Found '%s'", TagStr.CStr(), SymStr.CStr()).CStr());
1520  EAssertR(GetSym(TagVal) == xsyStr, "Expected string tag.");
1521  EAssertR(GetTag(TagStr) == xsyETag, TStr::Fmt("Expected '</%s>'. Found '%s'", TagStr.CStr(), SymStr.CStr()).CStr());
1522 }
1523 
1525  GetSym();
1526  EAssertR(TagStr==SymStr, TStr::Fmt("Expected xml symbol '%s'. Found '%s'",
1527  TagStr.CStr(), SymStr.CStr()).CStr());
1528  return Sym;
1529 }
1530 
1531 void TXmlParser::GetPlainStrFromXmlStr(const TChA& XmlStr, TChA& PlainChA) {
1532  static TChA EntityNm;
1533  PlainChA.Clr();
1534  const char *Ch = XmlStr.CStr();
1535  while (*Ch){
1536  if (*Ch!='&'){ PlainChA+=*Ch; Ch++; }
1537  else {
1538  if (*++Ch=='#'){
1539  TChA RefChA; int RefCd=0;
1540  if (*++Ch=='x'){
1541  forever { Ch++;
1542  if (TCh::IsHex(*Ch)){ RefChA+=*Ch; RefCd=RefCd*16+TCh::GetHex(*Ch); }
1543  else { break; } }
1544  } else { // decimal character code
1545  forever {
1546  if (TCh::IsNum(*Ch)){ RefChA+=*Ch; RefCd=RefCd*10+TCh::GetNum(*Ch); }
1547  else { break; } Ch++; }
1548  }
1549  if ((!RefChA.Empty())&&(*Ch==';')){
1550  Ch++; const uchar RefCh=uchar(RefCd); PlainChA+=RefCh; }
1551  } else {
1552  EntityNm.Clr();
1553  while ((*Ch)&&(*Ch!=';')){EntityNm+=*Ch; Ch++;}
1554  if ((!EntityNm.Empty())&&(*Ch==';')){ Ch++;
1555  if (EntityNm=="quot"){PlainChA+='"';}
1556  else if (EntityNm=="amp"){PlainChA+='&';}
1557  else if (EntityNm=="apos"){PlainChA+='\'';}
1558  else if (EntityNm=="lt"){PlainChA+='<';}
1559  else if (EntityNm=="gt"){PlainChA+='>';}
1560  }
1561  }
1562  }
1563  }
1564 }
TStr MsgStr
Definition: xml.h:329
#define IAssert(Cond)
Definition: bd.h:262
static bool IsHex(const char &Ch)
Definition: dt.h:1070
void SaveTxt(const PSOut &SOut)
Definition: xml.h:383
TChA NextSymStr
Definition: xml.h:405
void SkipTillTag(const TChA &_SymStr)
Definition: xml.cpp:1510
TChA SymStr
Definition: xml.h:405
TBSet PubidChSet
Definition: xml.h:46
TXmlLxSym GetSym()
Definition: xml.cpp:757
int GetArgs() const
Definition: xml.h:262
void PutSubTok(const PXmlTok &Tok, const int &SubTokN=-1)
Definition: xml.cpp:1134
TStr TagNm
Definition: xml.h:141
bool IsChar(const uchar &Ch) const
Definition: xml.h:68
void GetXmlDecl()
Definition: xml.cpp:531
TChA TxtChA
Definition: xml.h:140
void GetTagValV(const TStr &TagNm, const bool &XmlP, TStrV &ValV) const
Definition: xml.cpp:1171
Definition: xml.h:93
void GetEntity()
Definition: xml.cpp:690
Definition: xml.h:91
TStr GetStr() const
Definition: dt.h:1200
void GetArg(const int &ArgN, TStr &ArgNm, TStr &ArgVal) const
Definition: xml.h:263
int Len() const
Definition: dt.h:490
Definition: xml.h:93
void GetArg(const int &ArgN, TStr &ArgNm, TStr &ArgVal) const
Definition: xml.h:166
bool IsInt(const bool &Check, const int &MnVal, const int &MxVal, int &Val) const
Definition: dt.cpp:1159
TStr GetTagTokStrArgVal(const TStr &TagPath, const TStr &ArgNm, const TStr &DfVal=TStr()) const
Definition: xml.cpp:1356
bool GetTagTokBoolArgVal(const TStr &TagPath, const TStr &ArgNm, const bool &DfVal=false) const
Definition: xml.cpp:1332
void GetNData()
Definition: xml.cpp:622
TBSet CharChSet
Definition: xml.h:45
bool IsPEntityNm(const TStr &EntityNm, TStr &EntityVal) const
Definition: xml.h:179
TXmlLxSym NextSym
Definition: xml.h:404
Definition: bits.h:313
static TStr GetChRefFromYuEntRef(const TStr &YuEntRefStr)
Definition: xml.cpp:1072
TInt Chs
Definition: xml.h:44
static bool IsNum(const char &Ch)
Definition: dt.h:1067
static TStr GetXmlLxSymStr(const TXmlLxSym &XmlLxSym)
Definition: xml.cpp:904
virtual int PutCh(const char &Ch)=0
PSIn SIn
Definition: xml.h:101
PXmlTok Tok
Definition: xml.h:330
static TStr GetUsAsciiStrFromXmlStr(const TStr &EntRefStr)
Definition: xml.cpp:1056
Definition: xml.h:94
void AddArg(const TStr &ArgNm, const TStr &ArgVal)
Definition: xml.h:161
#define forever
Definition: bd.h:6
int Len() const
Definition: dt.h:134
void GetEq()
Definition: xml.cpp:408
bool Empty() const
Definition: dt.h:260
#define Fail
Definition: bd.h:238
bool Ok
Definition: xml.h:328
static TStr GetTagNm(const TStr &TypeNm)
Definition: xml.cpp:5
bool Empty() const
Definition: bd.h:501
TStr GetName()
Definition: xml.cpp:416
void PutCh(const int &ChN, const char &Ch)
Definition: dt.h:278
TXmlLxSym GetSym()
Definition: xml.cpp:1457
static PXmlTok New()
Definition: xml.h:212
void Clr()
Definition: dt.h:258
TChA ChStack
Definition: xml.h:103
void GetWs(const bool &IsRq)
Definition: xml.cpp:331
TStr GetSymStr() const
Definition: xml.cpp:835
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
double GetFltArgVal(const TStr &ArgNm, const double &DfVal=0) const
Definition: xml.cpp:1119
TSOut * SOut
Definition: xml.h:23
static TStr GetPlainStrFromXmlStr(const TStr &XmlStr)
Definition: xml.cpp:991
Definition: xml.h:90
static TStr GetXmlStrFromPlainMem(const TMem &PlainMem)
Definition: xml.cpp:945
TSIn & RSIn
Definition: xml.h:401
static int GetHex(const char &Ch)
Definition: dt.h:1072
TXmlTokV SubTokV
Definition: xml.h:203
int Len() const
Definition: dt.h:259
bool IsEntityNm(const TStr &EntityNm, TStr &EntityVal) const
Definition: xml.h:83
bool IsFirstNameCh(const uchar &Ch) const
Definition: xml.h:78
TStrStrH EntityNmToValH
Definition: xml.h:47
PXmlTok GetSubTok(const int &SubTokN) const
Definition: xml.h:294
static int64 GetInt64Arg(const PXmlTok &XmlTok, const TStr &Nm)
Definition: xml.cpp:89
static TXmlChDef ChDef
Definition: xml.h:100
void GetAttList()
Definition: xml.cpp:665
void SetChTy(TBSet &ChSet, const int &MnCh, const int &MxCh=-1)
Definition: xml.cpp:190
int GetTagTokIntArgVal(const TStr &TagPath, const TStr &ArgNm, const int &DfVal=0) const
Definition: xml.cpp:1340
static PSOut New(const int &MxBfL=1024)
Definition: fl.h:506
TStr GetAsStr() const
Definition: fl.cpp:869
void GetPI()
Definition: xml.cpp:562
void GetTagTokV(const TStr &TagPath, TXmlTokV &XmlTokV) const
Definition: xml.cpp:1319
void EThrow(const TStr &MsgStr) const
Definition: xml.cpp:885
static PXmlDoc LoadStr(const TStr &Str)
Definition: xml.cpp:1443
TBSet ExtChSet
Definition: xml.h:45
TChA _SymStr
Definition: xml.h:402
void ToNrSpacing()
Definition: xml.cpp:270
bool IsTagTok(const TStr &TagPath, PXmlTok &TagTok) const
Definition: xml.h:350
Definition: xml.h:96
TStr GetTokStr(const bool &XmlP=true) const
Definition: xml.h:316
void PutEntityVal(const TStr &Nm, const TStr &Val)
Definition: xml.h:177
Definition: dt.h:77
uchar PrevCh
Definition: xml.h:104
void SplitOnCh(TStr &LStr, const char &SplitCh, TStr &RStr) const
Definition: dt.cpp:901
TStr GetStalVal()
Definition: xml.cpp:513
char LastLastCh() const
Definition: dt.h:282
static const char EofCh
Definition: dt.h:1040
uchar GetCh()
Definition: xml.cpp:260
double GetTagTokFltArgVal(const TStr &TagPath, const TStr &ArgNm, const double &DfVal=0) const
Definition: xml.cpp:1348
static bool GetBoolArg(const PXmlTok &XmlTok, const TStr &Nm)
Definition: xml.cpp:59
void Incl(const int &BitN)
Definition: bits.h:344
static PSIn New(const TStr &FNm)
Definition: fl.cpp:290
TSIn & RSIn
Definition: xml.h:102
bool IsPubid(const uchar &Ch) const
Definition: xml.h:74
static bool IsWs(const char &Ch)
Definition: dt.h:1063
char GetCh()
Definition: xml.h:407
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
Definition: ds.h:1022
int ChangeStrAll(const TStr &SrcStr, const TStr &DstStr, const bool &FromStartP=false)
Definition: dt.cpp:1141
TXmlLxSym GetTag(const TChA &TagStr)
Definition: xml.cpp:1524
void AddSubTok(const PXmlTok &Tok)
Definition: xml.h:292
char * CStr()
Definition: dt.h:255
static void Throw(const TStr &MsgStr)
Definition: ut.h:187
void SaveStr(TStr &Str)
Definition: xml.cpp:1448
virtual bool Eof()=0
bool IsBool(bool &Val) const
Definition: dt.cpp:1153
Definition: xml.h:98
void AddTokToChA(const bool &XmlP, TChA &ChA) const
Definition: xml.cpp:1185
bool Eof() const
Definition: fl.h:548
static PSIn New(const TStr &Str)
Definition: dt.h:711
Definition: xml.h:93
static int GetNum(const char &Ch)
Definition: dt.h:1069
void GetExternalId()
Definition: xml.cpp:609
TStr GetStr() const
Definition: dt.h:1282
TStrKdV ArgNmValKdV
Definition: xml.h:142
static TStr GetTokVStr(const TXmlTokV &TokV, const bool &XmlP=true)
Definition: xml.cpp:1219
char LastCh() const
Definition: dt.h:281
Definition: xml.h:92
int LnChN
Definition: xml.h:105
TXmlObjSerTagNm(TSOut &_SOut, const bool &ETagP, const TStr &Nm, const TStr &TypeNm, const TStr &ArgNm="", const TStr &ArgVal="")
Definition: xml.cpp:121
static double GetFltArg(const PXmlTok &XmlTok, const TStr &Nm)
Definition: xml.cpp:104
int GetIntArgVal(const TStr &ArgNm, const int &DfVal=0) const
Definition: xml.cpp:1109
void PutPEntityVal(const TStr &Nm, const TStr &Val)
Definition: xml.h:181
TStr GetLc() const
Definition: dt.h:502
Definition: xml.h:93
TStr GetSymStr() const
Definition: xml.h:242
void SetEntityVal(const TStr &Nm, const TStr &Val)
Definition: xml.cpp:204
TXmlLxSym Sym
Definition: xml.h:404
TBSet CombChSet
Definition: xml.h:45
static char GetArgValQCh(const TStr &ArgVal)
Definition: xml.h:171
unsigned char uchar
Definition: bd.h:10
void Gen(const int &_Bits)
Definition: bits.cpp:182
Definition: xml.h:90
bool IsArg(const TStr &ArgNm) const
Definition: xml.h:265
bool GetBoolArgVal(const TStr &ArgNm, const bool &DfVal=false) const
Definition: xml.cpp:1089
TXmlSpacing
Definition: xml.h:96
void Trunc()
Definition: dt.cpp:420
Definition: fl.h:128
TStr GetVersionNum()
Definition: xml.cpp:473
Definition: xml.h:93
PXmlTok GetTagTok(const TStr &TagPath) const
Definition: xml.cpp:1298
static const char LfCh
Definition: dt.h:1038
bool IsTag() const
Definition: xml.h:247
static PXmlTok GetTok(TXmlLx &Lx)
Definition: xml.cpp:1228
TStr GetStr() const
Definition: dt.h:681
TXmlLxSym Sym
Definition: xml.h:200
int GetArgs() const
Definition: xml.h:165
Definition: xml.h:198
TStr GetReference()
Definition: xml.cpp:340
Definition: fl.h:495
void ClrSubTok()
Definition: xml.h:295
static int GetIntArg(const PXmlTok &XmlTok, const TStr &Nm)
Definition: xml.cpp:74
Definition: xml.h:93
Definition: dt.h:201
bool IsName(const uchar &Ch) const
Definition: xml.h:73
#define EAssert(Cond)
Definition: bd.h:280
static TStr GetXmlStr(const TStr &Str)
Definition: xml.cpp:1364
TStr GetEncName()
Definition: xml.cpp:493
TStr GetStr() const
Definition: xml.h:244
TXmlChDef()
Definition: xml.cpp:208
TBSet NameChSet
Definition: xml.h:46
void GetNotation()
Definition: xml.cpp:722
TStr Str
Definition: xml.h:201
bool IsFlt(const bool &Check, const double &MnVal, const double &MxVal, double &Val, const char &DecDelimCh='.') const
Definition: dt.cpp:1265
PXmlTok GetTagTok(const TStr &TagPath) const
Definition: xml.cpp:1142
TStrKdV ArgNmValV
Definition: xml.h:202
long long int64
Definition: bd.h:27
TStr GetFPosStr() const
Definition: xml.cpp:895
TXmlLxSym
Definition: xml.h:89
static bool IsTagNm(const TStr &Str)
Definition: xml.cpp:927
static bool SkipTopTag(const PSIn &SIn)
Definition: xml.cpp:1383
Definition: dt.h:412
char GetCh()
Definition: fl.h:549
TXmlLxSym PeekSym()
Definition: xml.cpp:1493
bool Empty() const
Definition: dt.h:491
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
TStr TagNm
Definition: xml.h:22
Definition: xml.h:92
void GetCDSect()
Definition: xml.cpp:733
TXmlSpacing Spacing
Definition: xml.h:106
int PutStr(const char *CStr)
Definition: fl.cpp:117
void GetTagTokV(const TStr &TagPath, TXmlTokV &XmlTokV) const
Definition: xml.cpp:1158
TSizeTy SearchForw(const TVal &Val, const TSizeTy &BValN=0) const
Returns the position of an element with value Val.
Definition: ds.h:1552
Definition: xml.h:92
TStr GetHex() const
Definition: dt.h:515
static const char CrCh
Definition: dt.h:1039
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
static PXmlDoc LoadTxt(TXmlLx &Lx)
Definition: xml.cpp:1401
static void GetPlainStrFromXmlStr(const TChA &XmlStr, TChA &PlainChA)
Definition: xml.cpp:1531
virtual TStr GetSNm() const
Definition: fl.cpp:20
TStr GetAttValue()
Definition: xml.cpp:457
TStr GetPEReference()
Definition: xml.cpp:397
void Push(const char &Ch)
Definition: dt.h:264
void GetElement()
Definition: xml.cpp:656
static PXmlTok LoadTxtElement(TXmlLx &Lx)
Definition: xml.cpp:1249
void ClrArgV()
Definition: xml.h:160
TBSet DigitChSet
Definition: xml.h:46
Definition: xml.h:90
void PutTagTokStr(const TStr &TagPath, const TStr &TokStr) const
Definition: xml.cpp:1312
void SkipWs()
Definition: xml.cpp:752
TXmlLxSym GetSym() const
Definition: xml.h:241
int LnN
Definition: xml.h:105
bool IsEntityNm(const TStr &EntityNm, TStr &EntityVal) const
Definition: xml.h:175
static const uchar Mx
Definition: dt.h:1098
TXmlLxSym Sym
Definition: xml.h:139
void GetDocTypeDecl()
Definition: xml.cpp:627
virtual char GetCh()=0
int EncodeUtf8(const TIntV &src, TIntV &dest) const
Definition: unicode.h:1792
int ChN
Definition: xml.h:105
void GetComment()
Definition: xml.cpp:436
TStr GetTagVal(const TStr &TagNm, const bool &XmlP) const
Definition: xml.cpp:1180
virtual char PeekCh()=0
~TXmlObjSerTagNm()
Definition: xml.cpp:182
char Pop()
Definition: dt.h:265
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
void SplitOnLastCh(TStr &LStr, const char &SplitCh, TStr &RStr) const
Definition: dt.cpp:912
static void AssertXmlHd(const PXmlTok &XmlTok, const TStr &Nm, const TStr &TypeNm)
Definition: xml.cpp:22
static void LoadTxtMiscStar(TXmlLx &Lx)
Definition: xml.cpp:1243
TStr GetSystemLiteral()
Definition: xml.cpp:583
bool IsWs(const uchar &Ch) const
Definition: xml.h:76
TStr GetPubidLiteral()
Definition: xml.cpp:596
static const TStr TrueStr
Definition: dt.h:984
TDat & AddDat(const TKey &Key)
Definition: hash.h:238
TBSet LetterChSet
Definition: xml.h:46
static PXmlDoc New()
Definition: xml.h:335
bool IsInt64(const bool &Check, const int64 &MnVal, const int64 &MxVal, int64 &Val) const
Definition: dt.cpp:1212
Definition: xml.h:42
uchar Ch
Definition: xml.h:104
TStr GetEntityValue()
Definition: xml.cpp:674
Definition: fl.h:535
Definition: xml.h:91
static TStrStrH TypeNmToTagNmH
Definition: xml.h:7
TKeyDat< TStr, TStr > TStrKd
Definition: ds.h:405
int GetSubToks() const
Definition: xml.h:293
void GetTagVal(const TChA &TagStr, TChA &TagVal)
Definition: xml.cpp:1518
Definition: dt.h:1093
TStr GetStrArgVal(const TStr &ArgNm, const TStr &DfVal=TStr()) const
Definition: xml.cpp:1129
static TStr GetXmlStrFromPlainStr(const TChA &PlainChA)
Definition: xml.cpp:968