| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- using Abp.Logging;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Xml;
- namespace VberZero.Tools.FileHelpers;
- public static class XmlHelper
- {
- /// <summary>
- /// XML转换成DataTable
- /// </summary>
- /// <param name="xmlDS"></param>
- /// <returns></returns>
- public static string ConvertDataTableToXML(this DataTable xmlDS)
- {
- XmlTextWriter writer = null;
- try
- {
- var stream = new MemoryStream();
- writer = new XmlTextWriter(stream, Encoding.UTF8);
- xmlDS.WriteXml(writer);
- int count = (int)stream.Length;
- byte[] arr = new byte[count];
- stream.Seek(0, SeekOrigin.Begin);
- stream.Read(arr, 0, count);
- UTF8Encoding utf = new UTF8Encoding();
- return utf.GetString(arr).Trim();
- }
- catch (Exception e)
- {
- LogHelper.LogException(e);
- return "";
- }
- finally
- {
- writer?.Close();
- }
- }
- /// <summary>
- /// XML转换成DataTable
- /// </summary>
- /// <param name="xmlData"></param>
- /// <returns></returns>
- public static DataSet ConvertXMLToDataSet(this string xmlData)
- {
- XmlTextReader reader = null;
- try
- {
- DataSet xmlDS = new DataSet();
- var stream = new StringReader(xmlData);
- reader = new XmlTextReader(stream);
- xmlDS.ReadXml(reader);
- return xmlDS;
- }
- catch (Exception e)
- {
- LogHelper.LogException(e);
- return null;
- }
- finally
- {
- reader?.Close();
- }
- }
- }
- /// <summary>
- /// Object mapping of a xml file
- /// </summary>
- public class XModel
- {
- /// <summary>
- /// Directory of this xml file
- /// </summary>
- public string XmlDirectory { get; set; }
- /// <summary>
- /// Xml file name
- /// </summary>
- public string FileName { get; set; }
- /// <summary>
- /// Xml file encode
- /// </summary>
- public string Encode { get; set; }
- /// <summary>
- /// Root tag
- /// </summary>
- public XmlTag Root { get; set; }
- /// <summary>
- /// XmlDocument object of this xml file
- /// </summary>
- private XmlDocument XmlDoc { get; set; }
- #region constructor
- /// <summary>
- /// Default constructor
- /// </summary>
- public XModel()
- {
- }
- /// <summary>
- /// Constructor: Create XmlModel from XmlTag and save xml file
- /// </summary>
- /// <param name="directory">directory</param>
- /// <param name="fileName">fileName</param>
- /// <param name="encode">encode type</param>
- /// <param name="root">root tag</param>
- public XModel(string directory, string fileName, string encode, XmlTag root)
- {
- CreateWithFile(directory, fileName, encode, root);
- }
- /// <summary>
- /// Constructor: Create XmlModel from XmlTag only
- /// </summary>
- /// <param name="root">root tag</param>
- public XModel(XmlTag root)
- {
- CreateWithOutFile(root);
- }
- /// <summary>
- /// Constructor: Read XmlModel From xml file
- /// </summary>
- /// <param name="directory">directory</param>
- /// <param name="fileName">fileName</param>
- public XModel(string directory, string fileName)
- {
- Read(directory, fileName);
- }
- /// <summary>
- /// Constructor: Read XmlModel From xml string
- /// </summary>
- /// <param name="xml">xml string</param>
- public XModel(string xml)
- {
- Read(xml);
- }
- #endregion constructor
- #region Create and Read XmlModel
- /// <summary>
- /// Create XmlModel from XmlTag and save xml file
- /// </summary>
- /// <param name="directory">directory</param>
- /// <param name="fileName">fileName</param>
- /// <param name="encode">encode type</param>
- /// <param name="root">root tag</param>
- public void CreateWithFile(string directory, string fileName, string encode, XmlTag root)
- {
- XmlDirectory = directory;
- FileName = fileName;
- Encode = encode;
- Root = root;
- Save();
- }
- /// <summary>
- /// Create XmlModel from XmlTag only
- /// </summary>
- /// <param name="root"></param>
- public void CreateWithOutFile(XmlTag root)
- {
- Root = root;
- }
- /// <summary>
- /// Read XmlModel From xml file
- /// </summary>
- /// <param name="directory">directory</param>
- /// <param name="fileName">fileName</param>
- public void Read(string directory, string fileName)
- {
- XmlDirectory = directory;
- FileName = fileName;
- XmlDoc = new XmlDocument();
- XmlDoc.Load(directory + fileName);
- Root = NodeToTag(XmlDoc.DocumentElement);
- }
- /// <summary>
- /// Read XmlModel From xml string
- /// </summary>
- /// <param name="xml">xml string</param>
- public void Read(string xml)
- {
- XmlDoc = new XmlDocument();
- XmlDoc.LoadXml(xml);
- Root = NodeToTag(XmlDoc.DocumentElement);
- }
- #endregion Create and Read XmlModel
- /// <summary>
- /// Get current XmlModel's XmlDocument type object
- /// </summary>
- /// <returns></returns>
- public XmlDocument GetXmlDocument()
- {
- //create XmlModel xmldoc is null
- if (XmlDoc == null)
- {
- XmlDoc = new XmlDocument();
- }
- //replace root
- if (XmlDoc.DocumentElement != null)
- {
- XmlDoc.RemoveChild(XmlDoc.DocumentElement);
- }
- XmlDoc.AppendChild(TagToNode(Root));
- //add or edit declaration
- if (XmlDoc.FirstChild is XmlDeclaration declaration)
- {
- if (!string.IsNullOrEmpty(Encode))
- {
- declaration.Encoding = Encode;
- }
- }
- else
- {
- if (string.IsNullOrEmpty(Encode))
- {
- throw new Exception("Encode can't be empty");
- }
- XmlDoc.InsertBefore(XmlDoc.CreateXmlDeclaration("1.0", Encode, ""), XmlDoc.FirstChild);
- }
- return XmlDoc;
- }
- /// <summary>
- /// Save Object to file
- /// XmlDirectory and FileName and Encode need to be set before save
- /// </summary>
- public void Save()
- {
- if (Root == null)
- {
- throw new Exception("Root can't be null");
- }
- if (string.IsNullOrEmpty(XmlDirectory) || string.IsNullOrEmpty(FileName))
- {
- throw new Exception("XmlDirectory and FileName need to be set before save");
- }
- //generate xmldocument
- GetXmlDocument();
- if (!Directory.Exists(XmlDirectory))
- {
- Directory.CreateDirectory(XmlDirectory);
- }
- XmlDoc.Save(XmlDirectory + FileName);
- }
- /// <summary>
- /// Delete file
- /// </summary>
- public void Delete()
- {
- if (File.Exists(XmlDirectory + FileName))
- {
- File.Delete(XmlDirectory + FileName);
- }
- }
- /// <summary>
- /// Get xml string
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- return GetXmlDocument().OuterXml;
- }
- #region Helper
- /// <summary>
- /// Recurtion transfer XmlNode into XmlTag
- /// </summary>
- /// <param name="node">XmlNode</param>
- /// <returns></returns>
- public XmlTag NodeToTag(XmlNode node)
- {
- //不转化注释
- for (int i = 0; i < node.ChildNodes.Count; i++)
- {
- if (node.ChildNodes[i].Name == ("#comment"))
- {
- node.RemoveChild(node.ChildNodes[i]);
- }
- }
- //判断当前节点类型返回对应类型节点
- if (node.ChildNodes.Count > 0 && node.FirstChild.NodeType != XmlNodeType.Text)
- {
- XmlChildTag childTag = new XmlChildTag(node.Name);
- //属性不为空添加属性
- if (node.Attributes != null)
- {
- foreach (XmlAttribute attr in node.Attributes)
- {
- childTag.Attrs.Add(attr.Name, attr.Value);
- }
- }
- //递归添加子节点
- foreach (XmlNode childNode in node.ChildNodes)
- {
- XmlTag tag = NodeToTag(childNode);
- if (tag is XmlChildTag xmlChildTag)//根据子节点类型加入对应列表
- {
- childTag.ChildTagList.Add(xmlChildTag);
- }
- else
- {
- childTag.BaseTagList.Add(tag as XmlBaseTag);
- }
- }
- return childTag;
- }
- else
- {
- XmlBaseTag baseTag = new XmlBaseTag(node.Name);
- //属性不为空添加属性
- if (node.Attributes != null)
- {
- foreach (XmlAttribute attr in node.Attributes)
- {
- baseTag.Attrs.Add(attr.Name, attr.Value);
- }
- }
- baseTag.InnerText = node.InnerText;
- return baseTag;
- }
- }
- /// <summary>
- /// Recurtion transfer XmlTag into XmlNode
- /// </summary>
- /// <param name="tag">XmlTag</param>
- /// <returns></returns>
- public XmlNode TagToNode(XmlTag tag)
- {
- XmlNode node = XmlDoc.CreateElement(tag.Name);
- foreach (var attr in tag.Attrs)
- {
- XmlAttribute xmlAttr = XmlDoc.CreateAttribute(attr.Key);
- xmlAttr.Value = attr.Value;
- node.Attributes?.Append(xmlAttr);
- }
- if (tag is XmlChildTag childTag)
- {
- if (childTag.BaseTagList.Count == 0 && childTag.ChildTagList.Count == 0)
- {
- throw new Exception("A XmlChildTag " + childTag.Name + "'s BaseTagList and ChildTagList can't both empty,if this tag don't have any child please use XmlBaseTag type");
- }
- //添加对应的子节点
- foreach (XmlBaseTag innerTag in childTag.BaseTagList)
- {
- node.AppendChild(TagToNode(innerTag));
- }
- foreach (XmlChildTag innerTag in childTag.ChildTagList)
- {
- node.AppendChild(TagToNode(innerTag));
- }
- }
- else
- {
- if (tag is XmlBaseTag baseTag) node.InnerText = baseTag.InnerText;
- }
- return node;
- }
- /// <summary>
- /// Quickly get a XmlChildTag
- /// </summary>
- /// <param name="tagNames">tag's name input by order</param>
- /// <returns></returns>
- public XmlChildTag GetChildTag(params string[] tagNames)
- {
- if (tagNames[0] != Root.Name)
- {
- throw new Exception("Root tag doesn't match");
- }
- if (!(Root is XmlChildTag))
- {
- throw new Exception("Root " + tagNames[0] + " must be XmlChildTag type");
- }
- XmlChildTag result = (XmlChildTag)Root;
- for (int i = 1; i < tagNames.Length; i++)
- {
- if (result != null && result.ChildTagList.All(t => t.Name != tagNames[i]))
- {
- throw new Exception("Can't find XmlChildTag tag " + tagNames[i] + " by the input tag names with this order");
- }
- result = result?.ChildTagList.FirstOrDefault(t => t.Name == tagNames[i]);
- }
- return result;
- }
- /// <summary>
- /// Quickly get a XmlBaseTag
- /// </summary>
- /// <param name="tagNames">按顺序输入的节点名称/tag's name input by order</param>
- /// <returns></returns>
- public XmlBaseTag GetBaseTag(params string[] tagNames)
- {
- if (tagNames[0] != Root.Name)
- {
- throw new Exception("Root tag doesn't match");
- }
- if (Root is XmlBaseTag tag)
- {
- if (tagNames.Length == 1)
- {
- return tag;
- }
- throw new Exception("Root " + tagNames[0] + " is XmlBaseTag type, don't have any childs");
- }
- XmlChildTag childTag = Root as XmlChildTag;
- for (int i = 1; i < tagNames.Length; i++)
- {
- if (childTag != null && (childTag.ChildTagList.All(t => t.Name != tagNames[i]) && childTag.BaseTagList.All(t => t.Name != tagNames[i])))
- {
- throw new Exception("Can't find XmlTag " + tagNames[i] + " by the input tag names with this order");
- }
- //最后一个节点查找BaseTagList,否则查找ChildTagList
- if (i == tagNames.Length - 1)
- {
- if (childTag != null && childTag.BaseTagList.Any(t => t.Name == tagNames[i]))
- {
- return childTag.BaseTagList.FirstOrDefault(t => t.Name == tagNames[i]);
- }
- throw new Exception("Tag:" + tagNames[i] + " must be XmlBaseTag type");
- }
- //找到对应XmlChildTag节点缩小查找范围
- if (childTag != null && childTag.ChildTagList.Any(t => t.Name == tagNames[i]))
- {
- childTag = childTag.ChildTagList.FirstOrDefault(t => t.Name == tagNames[i]);
- }
- else
- {
- throw new Exception("Tag:" + tagNames[i] + " must be XmlChildTag type");
- }
- }
- return null;
- }
- #endregion Helper
- }
- /// <summary>
- /// XmlTag: A xml tag
- /// </summary>
- public abstract class XmlTag
- {
- /// <summary>
- /// Name
- /// </summary>
- public string Name { get; set; }
- /// <summary>
- /// Attributes
- /// </summary>
- public Dictionary<string, string> Attrs { get; set; }
- }
- /// <summary>
- /// XmlChildTag: A XmlTag that at least have a XmlChildTag or XmlBaseTag inside
- /// </summary>
- public class XmlChildTag : XmlTag
- {
- /// <summary>
- /// XmlChildTags of this XmlChildTag
- /// </summary>
- public List<XmlChildTag> ChildTagList { get; set; }
- /// <summary>
- /// XmlBaseTags of this XmlChildTag
- /// </summary>
- public List<XmlBaseTag> BaseTagList { get; set; }
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="name">Tag's Name</param>
- public XmlChildTag(string name)
- {
- Name = name;
- Attrs = new Dictionary<string, string>();
- ChildTagList = new List<XmlChildTag>();
- BaseTagList = new List<XmlBaseTag>();
- }
- /// <summary>
- /// Get a XmlChildTag from this tag
- /// </summary>
- /// <param name="tagNames">tag's name input by order</param>
- /// <returns></returns>
- public XmlChildTag GetChildTag(params string[] tagNames)
- {
- XmlChildTag result = this;
- foreach (var tagName in tagNames)
- {
- if (result != null && result.ChildTagList.All(t => t.Name != tagName))
- {
- throw new Exception("Can't find XmlChildTag tag " + tagName + " by the input tag names with this order");
- }
- result = result?.ChildTagList.FirstOrDefault(t => t.Name == tagName);
- }
- return result;
- }
- /// <summary>
- /// Get a XmlBaseTag from this tag
- /// </summary>
- /// <param name="tagNames">tag's name input by order</param>
- /// <returns></returns>
- public XmlBaseTag GetBaseTag(params string[] tagNames)
- {
- XmlChildTag childTag = this;
- for (int i = 0; i < tagNames.Length; i++)
- {
- if (childTag != null && (childTag.ChildTagList.All(t => t.Name != tagNames[i]) && childTag.BaseTagList.All(t => t.Name != tagNames[i])))
- {
- throw new Exception("Can't find XmlTag tag " + tagNames[i] + " by the input tag names with this order");
- }
- //最后一个节点查找BaseTagList,否则查找ChildTagList
- if (i == tagNames.Length - 1)
- {
- if (childTag != null && childTag.BaseTagList.Any(t => t.Name == tagNames[i]))
- {
- return childTag.BaseTagList.FirstOrDefault(t => t.Name == tagNames[i]);
- }
- throw new Exception("Tag:" + tagNames[i] + " must be XmlBaseTag type");
- }
- //找到对应XmlChildTag节点缩小查找范围
- if (childTag != null && childTag.ChildTagList.Any(t => t.Name == tagNames[i]))
- {
- childTag = childTag.ChildTagList.FirstOrDefault(t => t.Name == tagNames[i]);
- }
- else
- {
- throw new Exception("Tag:" + tagNames[i] + " must be XmlChildTag type");
- }
- }
- return null;
- }
- }
- /// <summary>
- /// Xml基础标签:基础标签内不能有子标签,可以有内部文字
- /// XmlBaseTag:XmlBaseTag don't have child tag, but inner text
- /// </summary>
- public class XmlBaseTag : XmlTag
- {
- /// <summary>
- /// InnerText
- /// </summary>
- public string InnerText { get; set; }
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="name">Tag's Name</param>
- public XmlBaseTag(string name)
- {
- Name = name;
- Attrs = new Dictionary<string, string>();
- }
- }
- #region Test
- ////Create a xmlfile
- //public static void Create()
- //{
- // XmlChildTag rootTag = new XmlChildTag("Root");
- // rootTag.BaseTagList.Add(new XmlBaseTag("BaseTagOne"));
- // XModel myXModel = new XModel("D:\\XML\\", "MyXModel.xml", "utf-8", rootTag);
- // Console.WriteLine("Create success");
- //}
- ////Read a xml file
- //public static void Read()
- //{
- // XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml");
- // string rootName = myXml.Root.Name;
- // string baseTagOneName = (myXml.Root as XmlChildTag).BaseTagList.First().Name;
- // Console.WriteLine("Read success");
- //}
- ////Edit a xml file
- //public static void Edit()
- //{
- // XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml");
- // //edit root name and attributes
- // XmlChildTag root = myXml.Root as XmlChildTag;
- // root.Name = "NewRoot";
- // root.Attrs.Add("attr1", "value1");
- // //root add a child tag which have three base tag
- // XmlChildTag newChild = new XmlChildTag("NewChild");
- // newChild.BaseTagList.Add(new XmlBaseTag("BaseTagTwo"));
- // XmlBaseTag baseTagThree = new XmlBaseTag("BaseTagThree");
- // baseTagThree.Attrs.Add("testa", "testv");
- // newChild.BaseTagList.Add(baseTagThree);
- // newChild.BaseTagList.Add(new XmlBaseTag("BaseTagFour") { InnerText = "some text" });
- // root.ChildTagList.Add(newChild);
- // //save to file
- // myXml.Save();
- // Console.WriteLine("Edit success");
- //}
- ////Quickly Get and edit
- //public static void QuicklyGet()
- //{
- // XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml");
- // //GetChildTag
- // XmlChildTag childA = myXml.GetChildTag("NewRoot", "NewChild");
- // childA.Attrs.Add("find", "ture");
- // //GetBaseTag
- // XmlBaseTag baseTagTwo = myXml.GetBaseTag("NewRoot", "NewChild", "BaseTagTwo");
- // baseTagTwo.InnerText = "default return first tag be found";
- // //quickly get tag from a XmlChildTag
- // XmlChildTag childB = myXml.GetChildTag("NewRoot", "NewChild");
- // //lambda
- // XmlBaseTag target = childB.BaseTagList.Where(b => b.Attrs.Keys.Contains("testa")).First();
- // target.InnerText = "quickly get combine with lambda let you read write xml file very quick";
- // //continue quickly get
- // XmlBaseTag target2 = childB.GetBaseTag("BaseTagTwo");
- // target2.InnerText = "quickly get can be use on XmlChildTag too.";
- // myXml.Save();
- // Console.WriteLine("QuicklyGet success");
- //}
- ////Delete
- //public static void Delete()
- //{
- // XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml");
- // myXml.Delete();
- // Console.WriteLine("Delete success");
- //}
- ////To string
- //public static void PrintXModel()
- //{
- // XModel myXml = new XModel("D:\\XML\\", "MyXModel.xml");
- // Console.WriteLine(myXml.ToString());
- //}
- ////Create from tag only
- //public static void CreateWithOutFile()
- //{
- // XmlChildTag root = new XmlChildTag("root");
- // root.BaseTagList.Add(new XmlBaseTag("base") { InnerText = "test" });
- // XModel myXml = new XModel(root);
- // myXml.XmlDirectory = "d:\\";
- // myXml.FileName = "nofile.xml";
- // myXml.Encode = "utf-8";
- // myXml.Save();
- //}
- ////Read from xml String
- //public static void ReadXmlString()
- //{
- // XModel newxml = new XModel(new XModel("D:\\XML\\", "MyXModel.xml").ToString());
- // newxml.Root.Name = "newroot";
- // newxml.XmlDirectory = "d:\\";
- // newxml.FileName = "newxml.xml";
- // newxml.Encode = "gbk";
- // newxml.Save();
- //}
- #endregion Test
|