using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; namespace Xmind2UnityConfigCore { public static class TopicExt { public static int ToUnity(string xmindPath, string outDirPath) { if (!File.Exists(xmindPath)) { Console.WriteLine($"{xmindPath} is not exist!!"); return -1; } if(string.IsNullOrEmpty(outDirPath)) outDirPath = System.IO.Path.GetDirectoryName(xmindPath); //var zipArchive = ZipFile.o(openFileDialog.FileName); //zipArchive. //解压缩的临时路径 string tempPath = System.IO.Path.Combine( System.IO.Path.GetTempPath(), System.IO.Path.GetFileNameWithoutExtension(xmindPath)); if (Directory.Exists(tempPath)) Directory.Delete(tempPath, true); ZipFile.ExtractToDirectory(xmindPath, tempPath); string filePath = System.IO.Path.Combine(tempPath, "content.json"); string json = File.ReadAllText(filePath); //var xmind = JsonConvert.DeserializeObject(json); //转义title //string unescape = System.Text.RegularExpressions.Regex.Unescape(str); JArray jArray = JsonConvert.DeserializeObject(json) as JArray; var jobject_topic = jArray.First() as JObject; var jobject_rootTopic = jobject_topic["rootTopic"] as JObject; Topic rootTopic = ToTopic(jobject_rootTopic); //json = Newtonsoft.Json.JsonConvert.SerializeObject(rootTopic, Formatting.Indented); //Console.WriteLine(json); //string path = System.IO.Path.Combine( // System.IO.Path.GetDirectoryName(openFileDialog.FileName), // System.IO.Path.GetFileNameWithoutExtension(openFileDialog.FileName)+".json"); //File.WriteAllText(path, json); ToUnity(rootTopic, outDirPath); Console.WriteLine($@"success!!! out to {System.IO.Path.Combine(outDirPath, "unity")}"); return 0; } static Topic ToTopic(JObject jObject) { var topic = new Topic(); string str = jObject["title"].ToString(); string unescape = System.Text.RegularExpressions.Regex.Unescape(str); topic.title = unescape; if (jObject.ContainsKey("children")) { var children = jObject["children"] as JObject; if (!children.ContainsKey("attached")) { //什么都没有,假的 return topic; } var attached = children["attached"] as JArray; foreach (JObject subTopic in attached) { topic.children.Add(ToTopic(subTopic)); } } return topic; } static void ToUnity(Topic rootTopic, string path) { path = System.IO.Path.Combine(path, "unity"); if (!Directory.Exists(path)) Directory.CreateDirectory(path); //register \ntype=\"IUnityContainer\"\nname=\"root\"\n(根容器) //生成relationship.json RelationShip relationShip = ToRelationShip(rootTopic, path); string json = Newtonsoft.Json.JsonConvert.SerializeObject(relationShip, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(System.IO.Path.Combine(path, "relationship.json"), json); } static RelationShip ToRelationShip(Topic topic, string path) { RelationShip relationShip = new RelationShip(); var x_root = ToXElement(topic.title); string name = x_root.Attribute("name").Value; relationShip.Name = name; foreach (var subTopic in topic.children) { if (subTopic.title.Contains("(config文件)")) { //这是config文件 //root.config\n(config文件) var ss = subTopic.title.Split('\n'); string filename = ss[0].Trim(); relationShip.Path.Add(filename); string filepath = System.IO.Path.Combine(path, filename); //创建 xxx.config 文件 ToConfig(subTopic.children, filepath); } else //if (unescape.StartsWith("register")) { //这是子容器 var subRelationShip = ToRelationShip(subTopic, path); relationShip.Children.Add(subRelationShip); } } return relationShip; } static XElement ToXElement(string title) { //把全部 中文的 () 替换为 英文的 () title = new string(title.Select((c) => { switch (c) { case '(': return '('; case ')': return ')'; case '“': return '"'; case '”': return '"'; default: return c; } }).ToArray()); //删除全部注解 Regex regex_instruction = new Regex(@"\([\s\S]*\)"); title = regex_instruction.Replace(title, ""); //全部注解删除后,什么也没有 if (string.IsNullOrEmpty(title)) return null; Regex regex_xml = new Regex(@"\<([\s\S]*)/\>"); var match = regex_xml.Match(title); if (match.Success) { //它就是标准的xml格式 //把头尾的 < /> 删除 title = match.Groups[1].Value; } title = title.Trim(); //什么也没有 if (string.IsNullOrEmpty(title)) return null; //把全部 中文的 “” 替换为 英文的 " Regex regex = new Regex(@"(\S+)\s*=\s*""([\s\S]*)"""); var ss = title.Split('\n', ' '); var xname = ss.First().Trim(); XElement x = new XElement(xname); for (int i = 1; i < ss.Length; i++) { var s = ss[i].Trim(); match = regex.Match(s); if (match.Success) { string attrName = match.Groups[1].Value; string attrValue = match.Groups[2].Value; x.Add(new XAttribute(attrName, attrValue)); } } return x; } static XElement ToXElement(Topic topic) { XElement x = ToXElement(topic.title); if (x == null) return null; foreach (var sub in topic.children) { var x_sub = ToXElement(sub); if (x_sub == null) continue; x.Add(x_sub); } return x; } static void ToConfig(List topics, string filepath) { XDocument xdoc = new XDocument(); //创建根元素 XElement x_configuration = new XElement("configuration"); //把根元素添加到文件中 xdoc.Add(x_configuration); XElement x_configSections = new XElement("configSections"); x_configuration.Add(x_configSections); XElement x_section = new XElement("section"); x_configSections.Add(x_section); x_section.Add( new XAttribute("name", "unity"), new XAttribute("type", "Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration") ); //XNamespace ns = "http://schemas.microsoft.com/practices/2010/unity"; XElement x_unity = new XElement("unity");// (ns+"unity"); x_configuration.Add(x_unity); //找出全部assembly 与 alias var assemblies_topics = topics.FindAll(t => t.title.Trim().StartsWith("assembly")); foreach (var assemblies_topic in assemblies_topics) { foreach (var assembly_topic in assemblies_topic.children) { XElement x_assembly = new XElement("assembly"); x_unity.Add(x_assembly); x_assembly.Add(new XAttribute("name", assembly_topic.title)); foreach (var namespace_topic in assembly_topic.children) { XElement x_namespace = new XElement("namespace"); x_unity.Add(x_namespace); x_namespace.Add(new XAttribute("name", namespace_topic.title)); } } } var aliass_topics = topics.FindAll(t => t.title.Trim().StartsWith("alias")); foreach (var aliass_topic in aliass_topics) { foreach (var alias_topic in aliass_topic.children) { XElement x_alias = new XElement("alias"); x_unity.Add(x_alias); x_alias.Add(new XAttribute("alias", alias_topic.title)); x_alias.Add(new XAttribute("type", alias_topic.children[0].title)); } } topics.RemoveAll(t => t.title.Trim().StartsWith("assembly") || t.title.Trim().StartsWith("alias")); //容器 XElement x_container = new XElement("container"); x_unity.Add(x_container); foreach (var topic in topics) { var x = ToXElement(topic); if (x == null) continue; x_container.Add(x); } //保存 xdoc.Save(filepath); } } }