XmlHelper.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. using System.IO;
  2. using System.Net;
  3. using System.Xml;
  4. using System.Xml.Serialization;
  5. using System;
  6. using System.Text;
  7. using System.Collections.Generic;
  8. using System.Xml.Schema;
  9. using System.Dynamic;
  10. using System.Xml.Linq;
  11. using System.Linq;
  12. namespace EasyDevCore.Common
  13. {
  14. /// <summary>
  15. /// Xml Utils
  16. /// </summary>
  17. public sealed class XmlHelper
  18. {
  19. #region NodeNavigator Class
  20. /// <summary>
  21. /// Class required to navigate through children nodes
  22. /// </summary>
  23. private class NodeNavigator
  24. {
  25. // Recursively loop over a node subtree
  26. internal static void LoopThroughChildren(XmlTextWriter writer, XmlNode rootNode)
  27. {
  28. // Write the start tag
  29. if (rootNode.NodeType == XmlNodeType.Element)
  30. {
  31. writer.WriteStartElement(rootNode.Name);
  32. // Write any attributes
  33. foreach (XmlAttribute attr in rootNode.Attributes)
  34. {
  35. writer.WriteAttributeString(attr.Name, attr.Value);
  36. }
  37. // Write any child nodes
  38. foreach (XmlNode node in rootNode.ChildNodes)
  39. {
  40. LoopThroughChildren(writer, node);
  41. }
  42. // Write the end tag
  43. writer.WriteEndElement();
  44. }
  45. else
  46. {
  47. // Write any text
  48. if (rootNode.NodeType == XmlNodeType.Text)
  49. {
  50. writer.WriteString(rootNode.Value);
  51. }
  52. }
  53. }
  54. }
  55. #endregion
  56. #region Public Methods
  57. /// <summary>
  58. /// Converts XML document to string.
  59. /// </summary>
  60. /// <param name="xmlDoc">The XML doc.</param>
  61. /// <returns></returns>
  62. public static string DocToString(XmlDocument xmlDoc)
  63. {
  64. StringBuilder sb = new();
  65. StringWriter sw = new(sb);
  66. xmlDoc.Save(sw);
  67. return sw.ToString();
  68. }
  69. /// <summary>
  70. /// Gets the XML doc from URL
  71. /// </summary>
  72. /// <param name="stream">The stream.</param>
  73. /// <returns></returns>
  74. public static XmlDocument CreateDocument(Stream stream)
  75. {
  76. XmlDocument xmlDoc = new();
  77. XmlReaderSettings settings = new();
  78. //Bỏ qua ghi chú và các chỉ dẫn xử lý
  79. settings.IgnoreComments = true;
  80. settings.IgnoreProcessingInstructions = true;
  81. settings.IgnoreWhitespace = true;
  82. XmlReader reader = null;
  83. try
  84. {
  85. reader = XmlReader.Create(stream, settings);
  86. xmlDoc.Load(reader);
  87. }
  88. finally
  89. {
  90. if (reader != null)
  91. {
  92. reader.Close();
  93. }
  94. }
  95. return xmlDoc;
  96. }
  97. /// <summary>
  98. /// Creates the XML document.
  99. /// </summary>
  100. /// <param name="rootName">Name of the root.</param>
  101. /// <returns></returns>
  102. public static XmlDocument CreateDocument(string rootName)
  103. {
  104. XmlDocument doc = new();
  105. XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", "");
  106. doc.InsertBefore(decl, doc.DocumentElement);
  107. if (!string.IsNullOrEmpty(rootName))
  108. {
  109. XmlNode newNode = doc.CreateElement(rootName);
  110. doc.AppendChild(newNode);
  111. }
  112. return doc;
  113. }
  114. /// <summary>
  115. /// Creates the XML document.
  116. /// </summary>
  117. /// <returns></returns>
  118. public static XmlDocument CreateDocument()
  119. {
  120. return CreateDocument(string.Empty);
  121. }
  122. /// <summary>
  123. /// Adds the child node.
  124. /// </summary>
  125. /// <param name="parentNode">The parent node.</param>
  126. /// <param name="nodeNames">The node names.</param>
  127. /// <returns></returns>
  128. public static XmlNode[] AddChildNodes(XmlNode parentNode, params string[] nodeNames)
  129. {
  130. XmlDocument doc = parentNode.OwnerDocument;
  131. if (doc == null) //Root ?
  132. {
  133. doc = (XmlDocument)parentNode;
  134. }
  135. XmlNode[] list = new XmlNode[nodeNames.Length];
  136. for (int i = 0; i < nodeNames.Length; i++)
  137. {
  138. var newNode = doc.CreateElement(nodeNames[i]);
  139. list[i] = parentNode.AppendChild(newNode);
  140. }
  141. return list;
  142. }
  143. /// <summary>
  144. /// Adds the child node with attributes.
  145. /// </summary>
  146. /// <param name="parentNode">The parent node.</param>
  147. /// <param name="nodeName">Name of the node.</param>
  148. /// <param name="value">The value.</param>
  149. /// <param name="attrName">Name of the attr.</param>
  150. /// <param name="attrValue">The attr value.</param>
  151. /// <returns></returns>
  152. public static XmlNode AddSingleChildNode(XmlNode parentNode, string nodeName, object value, string attrName, string attrValue)
  153. {
  154. XmlDocument doc = parentNode.OwnerDocument;
  155. if (doc == null) //Root ?
  156. {
  157. doc = (XmlDocument)parentNode;
  158. }
  159. var newNode = doc.CreateElement(nodeName);
  160. if (attrName != null)
  161. {
  162. AddNodeAttribute(newNode, attrName, attrValue);
  163. }
  164. parentNode.AppendChild(newNode);
  165. newNode.InnerText = ConvertHelper.StringFrom(value);
  166. return newNode;
  167. }
  168. /// <summary>
  169. /// Adds the single child node with value
  170. /// </summary>
  171. /// <param name="parentNode">The parent node.</param>
  172. /// <param name="nodeName">Name of the node.</param>
  173. /// <param name="value">The value.</param>
  174. /// <returns></returns>
  175. public static XmlNode AddSingleChildNode(XmlNode parentNode, string nodeName, object value)
  176. {
  177. return AddSingleChildNode(parentNode, nodeName, value, null, null);
  178. }
  179. /// <summary>
  180. /// Selects the node.
  181. /// </summary>
  182. /// <param name="parentNode">The parent node.</param>
  183. /// <param name="nodeName">Name of the node.</param>
  184. /// <returns></returns>
  185. public static XmlNode SelectSingleNode(XmlNode parentNode, string nodeName)
  186. {
  187. return parentNode.SelectSingleNode(nodeName);
  188. }
  189. /// <summary>
  190. /// Selects the nodes.
  191. /// </summary>
  192. /// <param name="parentNode">The parent node.</param>
  193. /// <param name="nodeName">Name of the node.</param>
  194. /// <returns></returns>
  195. public static XmlNodeList SelectNodes(XmlNode parentNode, string nodeName)
  196. {
  197. return parentNode.SelectNodes(nodeName);
  198. }
  199. /// <summary>
  200. /// Selects the node.
  201. /// </summary>
  202. /// <param name="parentNode">The parent node.</param>
  203. /// <param name="attrName">Name of the attr.</param>
  204. /// <param name="attrValue">The attr value.</param>
  205. /// <returns></returns>
  206. public static XmlNode SelectSingleNode(XmlNode parentNode, string attrName, object attrValue)
  207. {
  208. XmlNode childNode = null;
  209. if (parentNode.HasChildNodes)
  210. {
  211. string nodeName = parentNode.ChildNodes[0].Name;
  212. string path = nodeName + "[@" + attrName + "='" + attrValue.ToString() + "']";
  213. childNode = parentNode.SelectSingleNode(path);
  214. }
  215. return childNode;
  216. }
  217. /// <summary>
  218. /// Sets the node value.
  219. /// </summary>
  220. /// <param name="node">The node.</param>
  221. /// <param name="nodeName">Name of the node.</param>
  222. /// <param name="value">The value.</param>
  223. /// <returns></returns>
  224. public static bool SetNodeValue(XmlNode node, string nodeName, object value)
  225. {
  226. bool success = false;
  227. try
  228. {
  229. node[nodeName].InnerText = ConvertHelper.StringFrom(value);
  230. success = true;
  231. }
  232. catch(Exception)
  233. {
  234. }
  235. return success;
  236. }
  237. /// <summary>
  238. /// Gets the node value string.
  239. /// </summary>
  240. /// <param name="node">The node.</param>
  241. /// <param name="nodeName">Name of the node.</param>
  242. /// <param name="defaultValue">The default value.</param>
  243. /// <returns></returns>
  244. public static string GetNodeValue(XmlNode node, string nodeName, string defaultValue)
  245. {
  246. string value = defaultValue;
  247. if(node[nodeName] != null)
  248. {
  249. value = node[nodeName].InnerText;
  250. }
  251. return value;
  252. }
  253. /// <summary>
  254. /// Gets the node value string.
  255. /// </summary>
  256. /// <param name="node">The node.</param>
  257. /// <param name="nodeName">Name of the node.</param>
  258. /// <returns></returns>
  259. public static string GetNodeValue(XmlNode node, string nodeName)
  260. {
  261. return GetNodeValue(node, nodeName, string.Empty);
  262. }
  263. /// <summary>
  264. /// Gets the node value.
  265. /// </summary>
  266. /// <typeparam name="T">The type of value.</typeparam>
  267. /// <param name="parentNode">The parent node.</param>
  268. /// <param name="nodeName">Name of the node.</param>
  269. /// <param name="defaultValue">The default value.</param>
  270. /// <returns></returns>
  271. public static T GetNodeValue<T>(XmlNode parentNode, string nodeName, T defaultValue)
  272. {
  273. #pragma warning disable CS8602 // Dereference of a possibly null reference.
  274. return ConvertHelper.StringTo<T>(parentNode[nodeName].InnerText, defaultValue);
  275. #pragma warning restore CS8602 // Dereference of a possibly null reference.
  276. }
  277. /// <summary>
  278. /// Gets the node value.
  279. /// </summary>
  280. /// <typeparam name="T">The type of value.</typeparam>
  281. /// <param name="parentNode">The parent node.</param>
  282. /// <param name="nodeName">Name of the node.</param>
  283. /// <returns></returns>
  284. public static T GetNodeValue<T>(XmlNode parentNode, string nodeName)
  285. {
  286. return GetNodeValue<T>(parentNode, nodeName, default);
  287. }
  288. /// <summary>
  289. /// Creates the node attribute.
  290. /// </summary>
  291. /// <param name="node">The node.</param>
  292. /// <param name="attrName">Name of the attr.</param>
  293. /// <param name="value">The value.</param>
  294. /// <returns></returns>
  295. public static XmlAttribute AddNodeAttribute(XmlNode node, string attrName, object value)
  296. {
  297. XmlAttribute attr = null;
  298. try
  299. {
  300. attr = node.OwnerDocument.CreateAttribute(attrName);
  301. attr.Value = value.ToString();
  302. node.Attributes.SetNamedItem(attr);
  303. }
  304. catch(Exception)
  305. {
  306. }
  307. return attr;
  308. }
  309. /// <summary>
  310. /// Sets the node attribute.
  311. /// </summary>
  312. /// <param name="node">The node.</param>
  313. /// <param name="attrName">Name of the attr.</param>
  314. /// <param name="value">The value.</param>
  315. /// <returns></returns>
  316. public static bool SetNodeAttribute(XmlNode node, string attrName, object value)
  317. {
  318. bool success = false;
  319. try
  320. {
  321. node.Attributes[attrName].Value = ConvertHelper.StringFrom(value);
  322. success = true;
  323. }
  324. catch(Exception)
  325. {
  326. }
  327. return success;
  328. }
  329. /// <summary>
  330. /// Copies the node attribute.
  331. /// </summary>
  332. /// <param name="fromNode">From node.</param>
  333. /// <param name="toNode">To node.</param>
  334. /// <param name="attrName">Name of the attr.</param>
  335. /// <returns></returns>
  336. public static bool CopyNodeAttribute(XmlNode fromNode, XmlNode toNode, string attrName)
  337. {
  338. bool success = true;
  339. try
  340. {
  341. XmlAttribute fromAttr = fromNode.Attributes[attrName];
  342. XmlAttribute toAttr = toNode.Attributes[attrName];
  343. if (fromAttr != null)
  344. {
  345. if (toAttr == null)
  346. {
  347. toAttr = AddNodeAttribute(toNode, attrName, fromAttr.Value);
  348. }
  349. else
  350. {
  351. SetNodeAttribute(toNode, attrName, fromAttr.Value);
  352. }
  353. }
  354. }
  355. catch(Exception)
  356. {
  357. success = false;
  358. }
  359. return success;
  360. }
  361. /// <summary>
  362. /// Gets the node attribute string.
  363. /// </summary>
  364. /// <param name="node">The node.</param>
  365. /// <param name="attrName">Name of the attr.</param>
  366. /// <param name="defaultValue">The default value.</param>
  367. /// <returns></returns>
  368. public static string GetNodeAttribute(XmlNode node, string attrName, string defaultValue)
  369. {
  370. string value = defaultValue;
  371. if (node != null && node.Attributes[attrName] != null)
  372. {
  373. try
  374. {
  375. value = node.Attributes[attrName].InnerText;
  376. }
  377. catch (Exception)
  378. {
  379. }
  380. }
  381. return value;
  382. }
  383. /// <summary>
  384. /// Gets the node attribute string.
  385. /// </summary>
  386. /// <param name="node">The node.</param>
  387. /// <param name="attrName">Name of the attr.</param>
  388. /// <returns></returns>
  389. public static string GetNodeAttribute(XmlNode node, string attrName)
  390. {
  391. return GetNodeAttribute(node, attrName, null);
  392. }
  393. /// <summary>
  394. /// Gets the node attribute.
  395. /// </summary>
  396. /// <typeparam name="T">The type of attribute.</typeparam>
  397. /// <param name="node">The node.</param>
  398. /// <param name="attrName">Name of the attr.</param>
  399. /// <param name="defaultValue">The default value.</param>
  400. /// <returns></returns>
  401. public static T GetNodeAttribute<T>(XmlNode node, string attrName, T defaultValue)
  402. {
  403. return ConvertHelper.StringTo<T>(node.Attributes[attrName].InnerText, defaultValue);
  404. }
  405. /// <summary>
  406. /// Gets the node attribute.
  407. /// </summary>
  408. /// <typeparam name="T">The type of attribute.</typeparam>
  409. /// <param name="node">The node.</param>
  410. /// <param name="attrName">Name of the attr.</param>
  411. /// <returns></returns>
  412. public static T GetNodeAttribute<T>(XmlNode node, string attrName)
  413. {
  414. return GetNodeAttribute<T>(node, attrName, default);
  415. }
  416. /// <summary>
  417. /// The XML node to string.
  418. /// </summary>
  419. /// <param name="node">The node.</param>
  420. /// <returns></returns>
  421. public static string NodeToString(XmlNode node)
  422. {
  423. StringWriter sw = new(new StringBuilder(""));
  424. XmlTextWriter writer = new(sw);
  425. writer.Formatting = Formatting.Indented;
  426. if (node == null)
  427. {
  428. writer.WriteStartElement(string.Empty);
  429. }
  430. else
  431. {
  432. writer.WriteStartElement(node.Name);
  433. // Write any attributes
  434. foreach (XmlAttribute attr in node.Attributes)
  435. {
  436. writer.WriteAttributeString(attr.Name, attr.Value);
  437. }
  438. // Write child nodes
  439. XmlNodeList nodes = node.SelectNodes("child::*");
  440. if (nodes != null)
  441. {
  442. foreach (XmlNode n in nodes)
  443. {
  444. NodeNavigator.LoopThroughChildren(writer, n);
  445. }
  446. }
  447. }
  448. writer.WriteEndElement();
  449. writer.Close();
  450. return sw.ToString();
  451. }
  452. /// <summary>
  453. /// The XmlNodeList to string.
  454. /// </summary>
  455. /// <param name="nodeList">The node list.</param>
  456. /// <returns></returns>
  457. public static string NodeListToString(XmlNodeList nodeList)
  458. {
  459. if (nodeList != null)
  460. {
  461. StringBuilder sb = new();
  462. foreach (XmlNode node in nodeList)
  463. {
  464. if (sb.Length == 0)
  465. sb.Append(NodeToString(node));
  466. else
  467. sb.Append("\r\n" + NodeToString(node));
  468. }
  469. return sb.ToString();
  470. }
  471. return string.Empty;
  472. }
  473. /// <summary>
  474. /// Serializes the specified value.
  475. /// </summary>
  476. /// <param name="value">The value.</param>
  477. /// <returns></returns>
  478. public static string Serialize(object value)
  479. {
  480. XmlSerializer serialize = new(value.GetType());
  481. XmlDocument doc = new();
  482. using (StringWriter writer = new())
  483. {
  484. serialize.Serialize(writer, value);
  485. doc.LoadXml(writer.GetStringBuilder().ToString());
  486. }
  487. return doc.OuterXml;
  488. }
  489. /// <summary>
  490. /// Deserializes the specified value.
  491. /// </summary>
  492. /// <typeparam name="T"></typeparam>
  493. /// <param name="value">The value.</param>
  494. /// <returns></returns>
  495. public static T Deserialize<T>(string value)
  496. {
  497. object result = Deserialize(value, typeof(T));
  498. if (result == null) return default;
  499. return (T)result;
  500. }
  501. /// <summary>
  502. /// Deserializes the specified value.
  503. /// </summary>
  504. /// <param name="value">The value.</param>
  505. /// <param name="type">The type.</param>
  506. /// <returns></returns>
  507. public static object Deserialize(string value, Type type)
  508. {
  509. XmlSerializer serializer = new(type);
  510. StringReader reader = new(value);
  511. try
  512. {
  513. return serializer.Deserialize(reader);
  514. }
  515. catch
  516. {
  517. }
  518. return null;
  519. }
  520. /// <summary>
  521. /// Replaces invalid XML characters in a string with their valid XML equivalent.
  522. /// </summary>
  523. /// <param name="value">The value within which to escape invalid characters.</param>
  524. public static string EscapeXML(string value)
  525. {
  526. return System.Security.SecurityElement.Escape(value);
  527. }
  528. /// <summary>
  529. /// Unescapes the XML.
  530. /// </summary>
  531. /// <param name="value">The value.</param>
  532. /// <returns></returns>
  533. public static string UnescapeXML(string value)
  534. {
  535. if (string.IsNullOrEmpty(value)) return value;
  536. if(value.IndexOf("&apos;") > -1) value = value.Replace("&apos;", "'");
  537. if (value.IndexOf("&quot;") > -1) value = value.Replace("&quot;", "\"");
  538. if (value.IndexOf("&gt;") > -1) value = value.Replace("&gt;", ">");
  539. if (value.IndexOf("&lt;") > -1) value = value.Replace("&lt;", "<");
  540. if (value.IndexOf("&amp;") > -1) value = value.Replace("&amp;", "&");
  541. return value;
  542. }
  543. #endregion
  544. }
  545. }