SnXmlNode.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Xml;
  6. namespace CommonTool
  7. {
  8. /// <summary>
  9. /// jtXmlNode 创建 xml 数据格式
  10. /// </summary>
  11. [Serializable]
  12. public class SnXmlNode : ICloneable
  13. {
  14. /// <summary>
  15. /// 节点构造函数
  16. /// </summary>
  17. /// <param name="pcName">节点名称</param>
  18. /// <param name="pcValue">节点值,是父节点的话,为空</param>
  19. public SnXmlNode(string pcName, string pcValue)
  20. {
  21. //this._Name = "";
  22. //this._Value = "";
  23. _depth = -1;
  24. _nodes = new List<SnXmlNode>();
  25. _name = pcName;
  26. _value = Utils.FormatXmlToCode(pcValue);
  27. _id = Guid.NewGuid().ToString();
  28. NodeType = XmlNodeType.Element;
  29. }
  30. // Fields
  31. private int _depth;
  32. private string _id;
  33. private string _name;
  34. private readonly List<SnXmlNode> _nodes;
  35. private string _value;
  36. object _tag;
  37. private XmlNodeType _nodeType ;
  38. public object Tag
  39. {
  40. get { return _tag; }
  41. set { _tag = value; }
  42. }
  43. protected XmlNodeType NodeType
  44. {
  45. get { return _nodeType; }
  46. set { _nodeType = value; }
  47. }
  48. private string _xmlDeclaration = "";
  49. /// <summary>
  50. /// xml 声明信息
  51. /// </summary>
  52. public string XmlDeclaration
  53. {
  54. get { return _xmlDeclaration; }
  55. set { _xmlDeclaration = value; }
  56. }
  57. private string _comment = "";
  58. /// <summary>
  59. /// 该节点注释信息
  60. /// </summary>
  61. public string Comment
  62. {
  63. get { return _comment; }
  64. set { _comment = value; }
  65. }
  66. /// <summary>
  67. /// 向xmlNode节点中添加一个子节点
  68. /// </summary>
  69. /// <param name="poNode"></param>
  70. public void AddChild(SnXmlNode poNode)
  71. {
  72. _nodes.Add(poNode);
  73. }
  74. /// <summary>
  75. /// 判断Node的子节点中是否包含该节点
  76. /// </summary>
  77. /// <param name="poNode"></param>
  78. /// <returns></returns>
  79. public bool Contains(SnXmlNode poNode)
  80. {
  81. return _nodes.Contains(poNode);
  82. }
  83. /// <summary>
  84. /// 新增一个不同的节点,如果已经包含此节点,则不增加
  85. /// </summary>
  86. /// <param name="poNode"></param>
  87. /// <returns></returns>
  88. public bool AddNewChild(SnXmlNode poNode)
  89. {
  90. bool lbRetVal = false;
  91. if (!Contains(poNode))
  92. {
  93. _nodes.Add(poNode);
  94. lbRetVal = true;
  95. }
  96. return lbRetVal;
  97. }
  98. public bool DeleteChild(SnXmlNode poNode)
  99. {
  100. bool lbRetVal = false;
  101. if (_nodes.Contains(poNode))
  102. {
  103. lbRetVal = _nodes.Remove(poNode);
  104. }
  105. return lbRetVal;
  106. }
  107. /// <summary>
  108. /// 判断两个节点对象是否相等
  109. /// </summary>
  110. /// <param name="obj"></param>
  111. /// <returns></returns>
  112. public override bool Equals(object obj)
  113. {
  114. return obj != null && (GetHashCode() == obj.GetHashCode());
  115. }
  116. public bool NameEqual(string pcName)
  117. {
  118. return UtilStr.UAndT(_name) == UtilStr.UAndT(pcName);
  119. }
  120. /// <summary>
  121. /// 根据节点名称得到其第一子层的节点
  122. /// </summary>
  123. /// <param name="pcNodeName">需要查找的子节点的名称</param>
  124. /// <returns></returns>
  125. public SnXmlNode GetChildNode(string pcNodeName)
  126. {
  127. string text1 = "";
  128. return GetChildNode(pcNodeName, ref text1, false);
  129. }
  130. /// <summary>
  131. /// 根据节点名称得到其第一子层的节点
  132. /// </summary>
  133. /// <param name="pcNodeName">需要查找的子节点的名称</param>
  134. /// <param name="pcMessage">没有查找到的节点名称</param>
  135. /// <param name="plMandatory">是否需要返回没有查找到的节点名称</param>
  136. /// <returns></returns>
  137. public SnXmlNode GetChildNode(string pcNodeName, ref string pcMessage, bool plMandatory)
  138. {
  139. SnXmlNode node1 = null;
  140. foreach (SnXmlNode node2 in _nodes)
  141. {
  142. if (UtilStr.UAndT(node2.Name) == UtilStr.UAndT(pcNodeName))
  143. {
  144. node1 = node2;
  145. break;
  146. }
  147. }
  148. if ((node1 == null) && plMandatory)
  149. {
  150. pcMessage = pcMessage + ((pcMessage == "") ? "" : "\r\n") + pcNodeName;
  151. }
  152. return node1;
  153. }
  154. /// <summary>
  155. /// 查找与传入的名称匹配的节点,优先查找同一深度的节点,如果没有再往下一深度的层查找配对的节点
  156. /// </summary>
  157. /// <param name="pcDepNodeName">需要匹配的节点名称</param>
  158. /// <returns></returns>
  159. public SnXmlNode GetDepChildNode(string pcDepNodeName)
  160. {
  161. return GetDepChildNode(Nodes, pcDepNodeName);
  162. }
  163. #region ICloneable 成员
  164. public object Clone()
  165. {
  166. SnXmlNode loRetVal = new SnXmlNode(Name, Value);
  167. foreach (SnXmlNode node in Nodes)
  168. {
  169. loRetVal.AddChild((SnXmlNode)node.Clone());
  170. }
  171. return loRetVal;
  172. }
  173. #endregion
  174. /// <summary>
  175. /// 根据节点名称,返回节点的值
  176. /// </summary>
  177. /// <param name="pcNodeName"></param>
  178. /// <returns></returns>
  179. public string GetChildValue(string pcNodeName)
  180. {
  181. string text1 = "";
  182. SnXmlNode node1 = GetChildNode(pcNodeName);
  183. if (node1 != null)
  184. {
  185. text1 = node1.Value.Trim();
  186. }
  187. return text1;
  188. }
  189. /// <summary>
  190. /// 给节点重新赋值,如果没有发现该节点则创建该节点
  191. /// </summary>
  192. /// <param name="pcNodeName"></param>
  193. /// <param name="pcValue"></param>
  194. public void SetChildValue(string pcNodeName, string pcValue)
  195. {
  196. SetChildValue(pcNodeName, pcValue, true);
  197. }
  198. /// <summary>
  199. /// 给节点重新赋值
  200. /// </summary>
  201. /// <param name="pcNodeName">节点名称</param>
  202. /// <param name="pcValue">节点值</param>
  203. /// <param name="pbAddNewIfNull">当节点为null的时候,是否创建该节点</param>
  204. public void SetChildValue(string pcNodeName, string pcValue, bool pbAddNewIfNull)
  205. {
  206. SnXmlNode loNode = GetChildNode(pcNodeName);
  207. if (loNode == null)
  208. {
  209. if (pbAddNewIfNull)
  210. {
  211. loNode = new SnXmlNode(pcNodeName, pcValue);
  212. AddChild(loNode);
  213. }
  214. }
  215. else
  216. {
  217. loNode.Value = pcValue;
  218. }
  219. }
  220. /// <summary>
  221. /// 节点的hash代码
  222. /// </summary>
  223. /// <returns></returns>
  224. public override int GetHashCode()
  225. {
  226. return Id.GetHashCode();
  227. }
  228. /// <summary>
  229. /// Object对象显示的值
  230. /// </summary>
  231. /// <returns></returns>
  232. public override string ToString()
  233. {
  234. string lcRetVal = Name;
  235. if (Value != "")
  236. {
  237. lcRetVal = lcRetVal + "=" + Value;
  238. }
  239. return lcRetVal;
  240. }
  241. /// <summary>
  242. /// 将该xmlNode 导成 xml字符串形式,不包括xml声明和所有的注释信息
  243. /// </summary>
  244. /// <returns></returns>
  245. public string ToXmlString()
  246. {
  247. return ToXmlString(0);
  248. }
  249. private string ToXmlString(int piDepth)
  250. {
  251. if (Nodes.Count == 0)
  252. {
  253. string lcText = "{2}<{0}>{1}</{0}>";
  254. return string.Format(lcText, Name, Utils.FormatCodeToXml(Value), UtilStr.Replicate(" ", piDepth));
  255. }
  256. string text3 = "{2}<{0}>\r\n{1}\r\n{2}</{0}>";
  257. string text4 = "";
  258. foreach (SnXmlNode node1 in Nodes)
  259. {
  260. text4 += ((text4 == "") ? "" : "\r\n") + node1.ToXmlString(piDepth + 1);
  261. }
  262. return string.Format(text3, Name, text4, UtilStr.Replicate(" ", piDepth));
  263. }
  264. /// <summary>
  265. /// 将该xmlNode 导成 xml字符串形式,包括xml声明和所有的注释信息
  266. /// </summary>
  267. /// <returns></returns>
  268. public string ToAllXmlString()
  269. {
  270. string lcRetVal = ToAllXmlString(0);
  271. if (_xmlDeclaration.Trim().Length > 0)
  272. lcRetVal = _xmlDeclaration + "\r\n" + lcRetVal;
  273. return lcRetVal;
  274. }
  275. private string ToAllXmlString(int piDepth)
  276. {
  277. string lcRetVal;
  278. if (Nodes.Count == 0)
  279. {
  280. string lcText = "{2}<{0}>{1}</{0}>";
  281. lcRetVal = string.Format(lcText, Name, Utils.FormatCodeToXml(Value), UtilStr.Replicate(" ", piDepth));
  282. }
  283. else
  284. {
  285. string text3 = "{2}<{0}>\r\n{1}\r\n{2}</{0}>";
  286. string text4 = "";
  287. foreach (SnXmlNode node1 in Nodes)
  288. {
  289. text4 += ((text4 == "") ? "" : "\r\n") + node1.ToAllXmlString(piDepth + 1);
  290. }
  291. lcRetVal = string.Format(text3, Name, text4, UtilStr.Replicate(" ", piDepth));
  292. }
  293. if (_comment.Trim().Length > 0)
  294. {
  295. lcRetVal = UtilStr.Replicate(" ", piDepth) + _comment + "\r\n" + lcRetVal;
  296. }
  297. return lcRetVal;
  298. }
  299. /// <summary>
  300. /// 节点深度
  301. /// </summary>
  302. public int Depth
  303. {
  304. get { return _depth; }
  305. set { _depth = value; }
  306. }
  307. /// <summary>
  308. /// 节点名称
  309. /// </summary>
  310. public string Name
  311. {
  312. get { return _name; }
  313. set { _name = value; }
  314. }
  315. /// <summary>
  316. /// 子节点集合
  317. /// </summary>
  318. public List<SnXmlNode> Nodes => _nodes;
  319. /// <summary>
  320. /// 节点值
  321. /// </summary>
  322. public string Value
  323. {
  324. get { return _value; }
  325. set { _value = value; }
  326. }
  327. public string Id
  328. {
  329. get { return _id; }
  330. set { _id = value; }
  331. }
  332. /// <summary>
  333. /// 从标准的xml文件转换成 snXmlNode 对象
  334. /// </summary>
  335. /// <param name="pcGenericXml"></param>
  336. /// <returns></returns>
  337. public static SnXmlNode ParseGenericXml(string pcGenericXml)
  338. {
  339. SnXmlNode loRetVal = null;
  340. //XmlDocument loDocument = new XmlDocument();
  341. //loDocument.LoadXml(pcGenericXml);
  342. StringReader loStrReader = new StringReader(pcGenericXml);
  343. XmlTextReader loXmlReader = new XmlTextReader(loStrReader);
  344. Hashtable hashtable1 = new Hashtable();
  345. string lcContent = "";
  346. string lcXmlDeclaration = "";
  347. try
  348. {
  349. while (loXmlReader.Read())
  350. {
  351. if (loXmlReader.NodeType == XmlNodeType.Element)
  352. {
  353. SnXmlNode node2 = new SnXmlNode(loXmlReader.Name, "");
  354. if (lcContent.Trim().Length > 0)
  355. {
  356. node2._comment = lcContent;
  357. lcContent = "";
  358. }
  359. node2.Depth = loXmlReader.Depth;
  360. if (hashtable1[loXmlReader.Depth] == null)
  361. {
  362. hashtable1.Add(loXmlReader.Depth, node2);
  363. }
  364. else
  365. {
  366. hashtable1[loXmlReader.Depth] = node2;
  367. }
  368. if (loXmlReader.Depth > 0)
  369. {
  370. ((SnXmlNode)hashtable1[loXmlReader.Depth - 1]).AddChild(node2);
  371. }
  372. else
  373. {
  374. loRetVal = node2;
  375. }
  376. }
  377. if (loXmlReader.NodeType == XmlNodeType.XmlDeclaration)
  378. {
  379. lcXmlDeclaration = "<?" + loXmlReader.Name + " " + loXmlReader.Value + "?>";
  380. }
  381. if (loXmlReader.NodeType == XmlNodeType.Comment)
  382. {
  383. lcContent = "<!--" + loXmlReader.Value + "-->";
  384. }
  385. if (loXmlReader.NodeType == XmlNodeType.Text)
  386. {
  387. ((SnXmlNode)hashtable1[loXmlReader.Depth - 1]).Value = Utils.FormatXmlToCode(loXmlReader.Value);
  388. }
  389. }
  390. if (loRetVal != null)
  391. {
  392. loRetVal._xmlDeclaration = lcXmlDeclaration;
  393. }
  394. }
  395. catch (Exception e)
  396. {
  397. throw new Exception(e.Message, e);
  398. }
  399. return loRetVal;
  400. }
  401. /// <summary>
  402. /// 查找与传入的名称匹配的节点,优先查找同一深度的节点,如果没有再往下一深度的层查找配对的节点
  403. /// </summary>
  404. /// <param name="poListNode">需要查找的节点层</param>
  405. /// <param name="pcDepNodeName">匹配的节点名称</param>
  406. /// <returns>返回匹配的同一个层中第一个节点</returns>
  407. public static SnXmlNode GetDepChildNode(List<SnXmlNode> poListNode, string pcDepNodeName)
  408. {
  409. SnXmlNode loRetVal = null;
  410. if (poListNode != null && poListNode.Count > 0)
  411. {
  412. List<SnXmlNode> loList = new List<SnXmlNode>();
  413. foreach (SnXmlNode loNode in poListNode)
  414. {
  415. if (loNode != null)
  416. {
  417. if (UtilStr.UAndT(loNode.Name) == UtilStr.UAndT(pcDepNodeName))
  418. {
  419. loRetVal = loNode;
  420. break;
  421. }
  422. foreach (SnXmlNode node in loNode.Nodes)
  423. {
  424. loList.Add(node);
  425. }
  426. }
  427. }
  428. if (loRetVal == null && loList.Count > 0)
  429. {
  430. loRetVal = GetDepChildNode(loList, pcDepNodeName);
  431. }
  432. }
  433. return loRetVal;
  434. }
  435. }
  436. }