You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

371 line
7.3 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. public class XMLParser
  4. {
  5. public XMLParser(string xmlString)
  6. {
  7. this.xmlString = xmlString;
  8. }
  9. public XMLParser()
  10. {
  11. this.xmlString = string.Empty;
  12. }
  13. public XMLElement XMLRootElement
  14. {
  15. get
  16. {
  17. return this.rootElement;
  18. }
  19. }
  20. public string XMLString
  21. {
  22. get
  23. {
  24. return this.xmlString;
  25. }
  26. set
  27. {
  28. this.xmlString = value;
  29. this.rootflag = false;
  30. }
  31. }
  32. public virtual XMLElement Parse(string xmlString)
  33. {
  34. this.xmlString = xmlString;
  35. return this.Parse();
  36. }
  37. public XMLElement Parse()
  38. {
  39. this.rootflag = false;
  40. string text = string.Empty;
  41. string tagName = string.Empty;
  42. string name = string.Empty;
  43. string arg = string.Empty;
  44. XMLTokenType xmltokenType = XMLTokenType.None;
  45. XMLTokenType xmltokenType2 = XMLTokenType.None;
  46. XMLParserAttrbuteMode xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name;
  47. this.attributeList = new List<XMLAttribute>();
  48. int i = 0;
  49. int length = this.xmlString.Length;
  50. while (i < length)
  51. {
  52. char c = this.xmlString[i];
  53. switch (c)
  54. {
  55. case ';':
  56. if (xmltokenType == XMLTokenType.Entity)
  57. {
  58. xmltokenType = xmltokenType2;
  59. text = arg + XMLParser.ParseEntityReference(text);
  60. }
  61. else
  62. {
  63. text += c;
  64. }
  65. break;
  66. case '<':
  67. {
  68. xmltokenType2 = xmltokenType;
  69. if (xmltokenType2 != XMLTokenType.Entity)
  70. {
  71. if (xmltokenType2 == XMLTokenType.Text)
  72. {
  73. this.TextHandler(text);
  74. }
  75. }
  76. else
  77. {
  78. this.EntityHandler(text);
  79. }
  80. char c2 = this.xmlString[i + 1];
  81. if (c2 != '!')
  82. {
  83. if (c2 != '/')
  84. {
  85. if (c2 != '?')
  86. {
  87. if (xmltokenType2 != XMLTokenType.Declaration)
  88. {
  89. if (xmltokenType2 != XMLTokenType.EntityElement)
  90. {
  91. xmltokenType = XMLTokenType.StartElement;
  92. }
  93. else
  94. {
  95. xmltokenType = XMLTokenType.EntityElement;
  96. }
  97. }
  98. else
  99. {
  100. xmltokenType = XMLTokenType.Declaration;
  101. }
  102. }
  103. else
  104. {
  105. xmltokenType = XMLTokenType.Declaration;
  106. i++;
  107. }
  108. }
  109. else
  110. {
  111. xmltokenType = XMLTokenType.EndElement;
  112. i++;
  113. }
  114. }
  115. else
  116. {
  117. xmltokenType = XMLTokenType.EntityElement;
  118. i++;
  119. }
  120. text = string.Empty;
  121. break;
  122. }
  123. case '=':
  124. if (xmltokenType != XMLTokenType.Attribute)
  125. {
  126. text += c;
  127. }
  128. else if (xmlparserAttrbuteMode != XMLParserAttrbuteMode.Name)
  129. {
  130. if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value)
  131. {
  132. text += c;
  133. }
  134. }
  135. else
  136. {
  137. name = text.Trim();
  138. text = string.Empty;
  139. xmlparserAttrbuteMode = XMLParserAttrbuteMode.Assignment;
  140. }
  141. break;
  142. case '>':
  143. xmltokenType2 = xmltokenType;
  144. switch (xmltokenType)
  145. {
  146. case XMLTokenType.Declaration:
  147. this.DeclarationHandler(text);
  148. break;
  149. case XMLTokenType.EntityElement:
  150. this.EntityHandler(text);
  151. break;
  152. case XMLTokenType.StartElement:
  153. this.StartElementHandler(text);
  154. if (this.xmlString[i - 1] == '/')
  155. {
  156. this.EndElementHandler(text);
  157. }
  158. break;
  159. case XMLTokenType.EndElement:
  160. this.EndElementHandler(text);
  161. break;
  162. case XMLTokenType.Attribute:
  163. this.StartElementHandler(tagName);
  164. xmltokenType2 = XMLTokenType.StartElement;
  165. break;
  166. }
  167. text = string.Empty;
  168. xmltokenType = XMLTokenType.Text;
  169. break;
  170. default:
  171. switch (c)
  172. {
  173. case ' ':
  174. if (xmltokenType != XMLTokenType.StartElement)
  175. {
  176. if (xmltokenType != XMLTokenType.Text)
  177. {
  178. if (xmltokenType == XMLTokenType.Attribute)
  179. {
  180. if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value)
  181. {
  182. text += c;
  183. }
  184. }
  185. }
  186. else
  187. {
  188. text += c;
  189. }
  190. }
  191. else
  192. {
  193. xmltokenType2 = xmltokenType;
  194. xmltokenType = XMLTokenType.Attribute;
  195. tagName = text;
  196. text = string.Empty;
  197. xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name;
  198. }
  199. break;
  200. default:
  201. if (c != '&')
  202. {
  203. text += c;
  204. }
  205. else
  206. {
  207. xmltokenType2 = xmltokenType;
  208. xmltokenType = XMLTokenType.Entity;
  209. arg = text;
  210. text = string.Empty;
  211. }
  212. break;
  213. case '"':
  214. if (xmltokenType == XMLTokenType.Attribute)
  215. {
  216. if (xmlparserAttrbuteMode != XMLParserAttrbuteMode.Assignment)
  217. {
  218. if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value)
  219. {
  220. this.AttributeHandler(name, text);
  221. text = string.Empty;
  222. xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name;
  223. }
  224. }
  225. else
  226. {
  227. xmlparserAttrbuteMode = XMLParserAttrbuteMode.Value;
  228. }
  229. }
  230. break;
  231. }
  232. break;
  233. }
  234. i++;
  235. }
  236. return this.rootElement;
  237. }
  238. protected virtual void DeclarationHandler(string content)
  239. {
  240. }
  241. protected virtual void EntityHandler(string content)
  242. {
  243. }
  244. protected virtual void StartElementHandler(string tagName)
  245. {
  246. XMLElement xmlelement;
  247. if (!this.rootflag)
  248. {
  249. xmlelement = new XMLElement(tagName.Trim(), null);
  250. this.rootElement = xmlelement;
  251. this.rootflag = true;
  252. }
  253. else
  254. {
  255. xmlelement = new XMLElement(tagName.Trim(), this.currentElement);
  256. }
  257. int i = 0;
  258. int count = this.attributeList.Count;
  259. while (i < count)
  260. {
  261. xmlelement.Attributes.Add(this.attributeList[i]);
  262. i++;
  263. }
  264. this.attributeList = new List<XMLAttribute>();
  265. this.currentElement = xmlelement;
  266. }
  267. protected virtual void EndElementHandler(string tagName)
  268. {
  269. if (this.rootflag && this.rootElement != this.currentElement)
  270. {
  271. this.currentElement = (XMLElement)this.currentElement.Parent;
  272. }
  273. }
  274. protected virtual void AttributeHandler(string name, string value)
  275. {
  276. this.attributeList.Add(new XMLAttribute(name.Trim(), value));
  277. }
  278. protected virtual void TextHandler(string text)
  279. {
  280. if (this.rootflag && text.Trim().Length > 0)
  281. {
  282. if (this.currentElement.Children.Count != 0)
  283. {
  284. IXMLNode ixmlnode = this.currentElement.Children[this.currentElement.Children.Count - 1];
  285. if (ixmlnode.type == XMLNodeType.Text)
  286. {
  287. IXMLNode ixmlnode2 = ixmlnode;
  288. ixmlnode2.value += text;
  289. return;
  290. }
  291. }
  292. new XMLText(text, this.currentElement);
  293. }
  294. }
  295. public static char ParseEntityReference(string entity)
  296. {
  297. if (entity != null)
  298. {
  299. if (entity == "lt")
  300. {
  301. return '<';
  302. }
  303. if (entity == "gt")
  304. {
  305. return '>';
  306. }
  307. if (entity == "quot")
  308. {
  309. return '"';
  310. }
  311. if (entity == "apos")
  312. {
  313. return '\'';
  314. }
  315. if (entity == "amp")
  316. {
  317. return '&';
  318. }
  319. }
  320. return '\0';
  321. }
  322. public static string GetEntityReference(char c)
  323. {
  324. if (c == '&')
  325. {
  326. return "&amp;";
  327. }
  328. if (c == '\'')
  329. {
  330. return "&apos;";
  331. }
  332. switch (c)
  333. {
  334. case '<':
  335. return "&lt;";
  336. default:
  337. if (c != '"')
  338. {
  339. return c.ToString();
  340. }
  341. return "&quot;";
  342. case '>':
  343. return "&gt;";
  344. }
  345. }
  346. protected XMLElement rootElement;
  347. protected XMLElement currentElement;
  348. protected bool rootflag;
  349. protected List<XMLAttribute> attributeList;
  350. protected string xmlString;
  351. }