实现一个简单的xml解析器,实现树状打印即可,不要使用第三方库,只允许自己分析字符串。编程语言不限。
(GPT提供的答案)
| <test> |
| "main" |
| <a1 key1="hoolai1" key2="company1"/> |
| <name1 key1="super1">"cctv1"</name1> |
| <int1>666 </int1> |
| <second> |
| <a2 key1="hoolai2" key2="company2"/> |
| <name2 key1="super2">"cctv2"</name2> |
| <int2>777 </int2> |
| </second> |
| <char1> "c" </char1> |
| </test> |
| sing System; |
| using System.Collections.Generic; |
| using System.IO; |
| using System.Linq; |
| using System.Text; |
| using System.Threading.Tasks; |
| using System.Xml; |
| |
| namespace 简单xml解析器 |
| { |
| class Node |
| { |
| public string Name { get; set; } |
| public List<Node> Children { get; private set; } = new List<Node>(); |
| public Node Parent { get; set; } |
| public Node(string name, Node parent) |
| { |
| this.Name = name; |
| this.Parent = parent; |
| } |
| |
| } |
| |
| class Program |
| { |
| |
| static Node Parse(string xml) |
| { |
| var stack = new Stack<Node>(); |
| Node current = null; |
| |
| for (int i = 0; i < xml.Length; i++) |
| { |
| if (xml[i] == '<') |
| { |
| |
| int tagStart = i + 1; |
| int tagEnd = xml.IndexOf('>', tagStart); |
| |
| if (tagEnd < 0) throw new Exception("Invalid XML"); |
| |
| if (xml[tagStart] == '/') |
| { |
| |
| if (stack.Count == 0) throw new Exception("Invalid XML"); |
| |
| current = stack.Pop(); |
| int tagNameStart = tagStart + 1; |
| int tagNameEnd = tagEnd; |
| if (xml.Substring(tagNameStart, tagNameEnd - tagNameStart) != current.Name) |
| throw new Exception("Invalid XML"); |
| } |
| else if (xml[tagEnd - 1] == '/') |
| { |
| |
| string tagName = xml.Substring(tagStart, tagEnd - tagStart - 1); |
| var node = new Node(tagName, current); |
| current.Children.Add(node); |
| } |
| else |
| { |
| |
| string tagName = xml.Substring(tagStart, tagEnd - tagStart); |
| var node = new Node(tagName, current); |
| stack.Push(node); |
| if (current != null) current.Children.Add(node); |
| current = node; |
| } |
| |
| i = tagEnd; |
| } |
| else if (xml[i] == '>') |
| { |
| |
| } |
| else |
| { |
| |
| int textStart = i; |
| int textEnd = xml.IndexOf('<', textStart); |
| |
| if (textEnd < 0) throw new Exception("Invalid XML"); |
| |
| string text = xml.Substring(textStart, textEnd - textStart) |
| .Trim('\n', '\r', ' ', '\t'); |
| if (text.Length > 0) current.Children.Add(new Node(text, current)); |
| |
| i = textEnd - 1; |
| } |
| } |
| |
| return current; |
| } |
| |
| |
| static void Print(Node root, string indent) |
| { |
| Console.WriteLine("{0}<{1}>", indent, root.Name); |
| foreach (var child in root.Children) |
| Print(child, indent + " "); |
| Console.WriteLine("{0}<{1}>", indent, root.Name); |
| } |
| |
| static void Main(string[] args) |
| { |
| |
| string xml; |
| using (StreamReader sr = new StreamReader(@"F:\学习资料\example.xml")) |
| { |
| xml= sr.ReadToEnd(); |
| Console.WriteLine(xml); |
| } |
| |
| var root = Parse(xml); |
| Print(root, ""); |
| } |
| } |
| } |
| |