Unity相关笔试题 实现一个简单的xml解析器,实现树状打印即可,不要使用第三方库,只允许自己分析字符串
实现一个简单的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)
{
//XmlDocument doc = new XmlDocument();
string xml;
using (StreamReader sr = new StreamReader(@"F:\学习资料\example.xml"))
{
xml= sr.ReadToEnd();
Console.WriteLine(xml);
}
var root = Parse(xml);
Print(root, "");
}
}
}