xmlutils.pp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. {
  2. This file is part of the Free Component Library
  3. XML utility routines.
  4. Copyright (c) 2006 by Sergei Gorelkin, [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit xmlutils;
  12. interface
  13. uses
  14. SysUtils;
  15. function IsXmlName(const Value: WideString; Xml11: Boolean = False): Boolean;
  16. function IsXmlNames(const Value: WideString; Xml11: Boolean = False): Boolean;
  17. function IsXmlNmToken(const Value: WideString; Xml11: Boolean = False): Boolean;
  18. function IsXmlNmTokens(const Value: WideString; Xml11: Boolean = False): Boolean;
  19. function IsValidXmlEncoding(const Value: WideString): Boolean;
  20. function Xml11NamePages: PByteArray;
  21. procedure NormalizeSpaces(var Value: WideString);
  22. {$i names.inc}
  23. implementation
  24. var
  25. Xml11Pg: PByteArray = nil;
  26. function Xml11NamePages: PByteArray;
  27. var
  28. I: Integer;
  29. p: PByteArray;
  30. begin
  31. if Xml11Pg = nil then
  32. begin
  33. GetMem(p, 512);
  34. for I := 0 to 255 do
  35. p^[I] := ord(Byte(I) in Xml11HighPages);
  36. p^[0] := 2;
  37. p^[3] := $2c;
  38. p^[$20] := $2a;
  39. p^[$21] := $2b;
  40. p^[$2f] := $29;
  41. p^[$30] := $2d;
  42. p^[$fd] := $28;
  43. Move(p^, p^[256], 256);
  44. p^[$100] := $19;
  45. p^[$103] := $2E;
  46. p^[$120] := $2F;
  47. Xml11Pg := p;
  48. end;
  49. Result := Xml11Pg;
  50. end;
  51. function IsXml11Char(const Value: WideString; var Index: Integer): Boolean;
  52. begin
  53. if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
  54. begin
  55. Inc(Index);
  56. Result := (Value[Index] >= #$DC00) and (Value[Index] <= #$DFFF);
  57. end
  58. else
  59. Result := False;
  60. end;
  61. function IsXmlName(const Value: WideString; Xml11: Boolean): Boolean;
  62. var
  63. Pages: PByteArray;
  64. I: Integer;
  65. begin
  66. Result := False;
  67. if Xml11 then
  68. Pages := Xml11NamePages
  69. else
  70. Pages := @NamePages;
  71. I := 1;
  72. if (Value = '') or not ((Byte(Value[I]) in NamingBitmap[Pages^[hi(Word(Value[I]))]]) or
  73. (Xml11 and IsXml11Char(Value, I))) then
  74. Exit;
  75. Inc(I);
  76. while I <= Length(Value) do
  77. begin
  78. if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
  79. (Xml11 and IsXml11Char(Value, I))) then
  80. Exit;
  81. Inc(I);
  82. end;
  83. Result := True;
  84. end;
  85. function IsXmlNames(const Value: WideString; Xml11: Boolean): Boolean;
  86. var
  87. Pages: PByteArray;
  88. I: Integer;
  89. Offset: Integer;
  90. begin
  91. if Xml11 then
  92. Pages := Xml11NamePages
  93. else
  94. Pages := @NamePages;
  95. Result := False;
  96. if Value = '' then
  97. Exit;
  98. I := 1;
  99. Offset := 0;
  100. while I <= Length(Value) do
  101. begin
  102. if not ((Byte(Value[I]) in NamingBitmap[Pages^[Offset+hi(Word(Value[I]))]]) or
  103. (Xml11 and IsXml11Char(Value, I))) then
  104. begin
  105. if (I = Length(Value)) or (Value[I] <> #32) then
  106. Exit;
  107. Offset := 0;
  108. Inc(I);
  109. Continue;
  110. end;
  111. Offset := $100;
  112. Inc(I);
  113. end;
  114. Result := True;
  115. end;
  116. function IsXmlNmToken(const Value: WideString; Xml11: Boolean): Boolean;
  117. var
  118. I: Integer;
  119. Pages: PByteArray;
  120. begin
  121. if Xml11 then
  122. Pages := Xml11NamePages
  123. else
  124. Pages := @NamePages;
  125. Result := False;
  126. if Value = '' then
  127. Exit;
  128. I := 1;
  129. while I <= Length(Value) do
  130. begin
  131. if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
  132. (Xml11 and IsXml11Char(Value, I))) then
  133. Exit;
  134. Inc(I);
  135. end;
  136. Result := True;
  137. end;
  138. function IsXmlNmTokens(const Value: WideString; Xml11: Boolean): Boolean;
  139. var
  140. I: Integer;
  141. Pages: PByteArray;
  142. begin
  143. if Xml11 then
  144. Pages := Xml11NamePages
  145. else
  146. Pages := @NamePages;
  147. I := 1;
  148. Result := False;
  149. if Value = '' then
  150. Exit;
  151. while I <= Length(Value) do
  152. begin
  153. if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
  154. (Xml11 and IsXml11Char(Value, I))) then
  155. begin
  156. if (I = Length(Value)) or (Value[I] <> #32) then
  157. Exit;
  158. end;
  159. Inc(I);
  160. end;
  161. Result := True;
  162. end;
  163. function IsValidXmlEncoding(const Value: WideString): Boolean;
  164. var
  165. I: Integer;
  166. begin
  167. Result := False;
  168. if (Value = '') or (Value[1] > #255) or not (char(ord(Value[1])) in ['A'..'Z', 'a'..'z']) then
  169. Exit;
  170. for I := 2 to Length(Value) do
  171. if (Value[I] > #255) or not (char(ord(Value[I])) in ['A'..'Z', 'a'..'z', '0'..'9', '.', '_', '-']) then
  172. Exit;
  173. Result := True;
  174. end;
  175. procedure NormalizeSpaces(var Value: WideString);
  176. var
  177. I, J: Integer;
  178. begin
  179. I := Length(Value);
  180. // speed: trim only whed needed
  181. if (I > 0) and ((Value[1] = #32) or (Value[I] = #32)) then
  182. Value := Trim(Value);
  183. I := 1;
  184. while I < Length(Value) do
  185. begin
  186. if Value[I] = #32 then
  187. begin
  188. J := I+1;
  189. while (J <= Length(Value)) and (Value[J] = #32) do Inc(J);
  190. if J-I > 1 then Delete(Value, I+1, J-I-1);
  191. end;
  192. Inc(I);
  193. end;
  194. end;
  195. initialization
  196. finalization
  197. if Assigned(Xml11Pg) then
  198. FreeMem(Xml11Pg);
  199. end.