-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathXmlFile.cs
More file actions
134 lines (110 loc) · 4.3 KB
/
XmlFile.cs
File metadata and controls
134 lines (110 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System.Text;
using System.Xml;
namespace UnityModPackager;
public class XmlFile
{
public string Base { get; private set; }
private XmlDocument _xmlDoc;
private string? _fileName;
public XmlFile(string path) : this(File.ReadAllBytes(path))
{
_fileName = path;
}
public XmlFile(byte[] fileData)
{
_xmlDoc = new XmlDocument();
Base = System.Text.Encoding.UTF8.GetString(fileData);
var byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (Base.StartsWith(byteOrderMarkUtf8))
Base = Base.Remove(0, byteOrderMarkUtf8.Length);
_xmlDoc.LoadXml(Base);
}
public bool ContainsChild(string text)
{
text = RemoveWhitespace(text);
return _xmlDoc.DocumentElement!.ChildNodes.Cast<XmlLinkedNode>().Any(child => RemoveWhitespace(child.OuterXml) == text);
}
public void RemoveChild(string text)
{
text = RemoveWhitespace(text);
_xmlDoc.DocumentElement!.ChildNodes.Cast<XmlLinkedNode>().Where(c => RemoveWhitespace(c.OuterXml) == text)
.ToList()
.ForEach(c => _xmlDoc.DocumentElement.RemoveChild(c));
}
public void InsertText(int index, string text)
=> Base = Base.Insert(index, text);
public void SaveBase()
{
if (_fileName is null)
throw new InvalidOperationException("File name is not set.");
File.WriteAllText(_fileName, Base);
}
public void SaveDocument()
{
if (_fileName is null)
throw new InvalidOperationException("File name is not set.");
using var writer = new XmlTextWriter(_fileName, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
_xmlDoc.Save(writer);
}
private static string RemoveWhitespace(string str)
=> System.Text.RegularExpressions.Regex.Replace(str, @"\s+", "");
public void AppendChild(string text)
{
var node = new XmlDocument();
node.LoadXml(text);
_xmlDoc.DocumentElement?.AppendChild(_xmlDoc.ImportNode(node.DocumentElement!, true));
}
public void RemoveAttribute(string text)
{
_xmlDoc.DocumentElement?.RemoveAttribute(text);
}
public void RemoveItem(string target, params (string attribute, string value)[] attributes)
{
var nodes = _xmlDoc.GetElementsByTagName(target).Cast<XmlElement>().ToArray();
foreach (var node in nodes)
{
if (attributes.All(attr => node.GetAttribute(attr.attribute) == attr.value))
{
node.ParentNode?.RemoveChild(node);
}
}
}
public void AddAttribute(string tag, string name, object value)
{
var nodes = _xmlDoc.GetElementsByTagName(tag).Cast<XmlElement>().ToArray();
foreach (var node in nodes)
node.SetAttribute(name, value.ToString()?.ToLowerInvariant());
}
public void AddTagToRoot(string tag, params (string Name, string Value)[] attributes)
{
var node = _xmlDoc.CreateElement(tag);
foreach (var attribute in attributes)
{
var attr = _xmlDoc.CreateAttribute(attribute.Name);
attr.Value = attribute.Value;
node.Attributes.Append(attr);
}
// make sure the tag (or a copy of) is not already in the root
if (_xmlDoc.DocumentElement?.ChildNodes.Cast<XmlLinkedNode>().Any(c => c.OuterXml == node.OuterXml) == true)
return;
_xmlDoc.DocumentElement?.AppendChild(node);
}
public void AddTag(string tag, string name, object value)
{
var nodes = _xmlDoc.GetElementsByTagName(tag).Cast<XmlElement>().ToArray();
foreach (var node in nodes)
if (!node.InnerXml.Contains("<" + name + ">"))
node.InnerXml += $"<{name}>{value.ToString()?.ToLowerInvariant()}</{name}>";
}
public void AddTagToFirst(string tag, string name, bool value)
{
var node = _xmlDoc.GetElementsByTagName(tag).Cast<XmlElement>().First();
if (node.InnerXml.Contains("<" + name + ">"))
return;
var newNode = _xmlDoc.CreateElement(name);
newNode.InnerText = value.ToString().ToLowerInvariant();
node.AppendChild(newNode);
}
}