Skip to content

Instantly share code, notes, and snippets.

@magicoal-nerb
Created January 12, 2026 01:08
Show Gist options
  • Select an option

  • Save magicoal-nerb/9a094080f84799c5d0261cb5e1a100b1 to your computer and use it in GitHub Desktop.

Select an option

Save magicoal-nerb/9a094080f84799c5d0261cb5e1a100b1 to your computer and use it in GitHub Desktop.
xml in C#
using System;
using System.Collections.Generic;
// Xml element
public class XmlElement {
// Current XML tag
public string tag;
// Current XML body
public string body;
// Current XML props
public Dictionary<string, string> props;
// Current Elements
public List<int> elements;
// Current parent
public int parent;
public XmlElement(string tag_, int parent_) {
elements = new List<int>();
parent = parent_;
props = new Dictionary<string, string>();
tag = tag_;
}
public float readFloat() {
// Reads the current body and parses it
return float.Parse(body);
}
};
// Reads in XML-compliant files efficiently.
// Files that do not comply may output undefined behavior.
public class Xml {
// Holds the array portion of the xml
private char[] content;
// Holds the length
private int length;
// Used for fast substring
private string data;
// Current reader position
private int cursor = 0;
// Current element list
public List<XmlElement> elements;
// Current node
private int node = 0;
public Xml(string content_) {
elements = new List<XmlElement>();
content = content_.ToCharArray();
length = content.Length;
data = content_;
}
private void skipWhitespace() {
// Skips through whitespace
while(cursor < length && Char.IsWhiteSpace(content[cursor])) {
cursor++;
}
}
private string parseLiteral() {
// Parses the literal
int left = cursor;
while(Char.IsLetterOrDigit(content[cursor]) || content[cursor] == ':') {
cursor++;
}
return data.Substring(left, cursor - left);
}
private void parseClosingElement() {
// We check the ending label
// and go up the node.
cursor++;
parseLiteral();
cursor++;
XmlElement currentNode = elements[node];
node = currentNode.parent;
}
private string parseString() {
// We assume that we start off
// with a open "
cursor++;
int left = cursor;
while(cursor < length && content[cursor] != '"') {
cursor++;
}
cursor++;
return data.Substring(left, cursor - left - 1);
}
private void parseNewElement() {
// Otherwise, we need to scan the other fields
// in here!
string type = parseLiteral();
int id = elements.Count;
XmlElement element = new XmlElement(type, node);
elements.Add(element);
// Read the other props inside of the element
while(content[cursor] != '>') {
// Go through whitespace!
skipWhitespace();
// Expects a `literal`="string"
string key = parseLiteral();
cursor += 1;
element.props[key] = parseString();
}
// Then, if it does not start with a <, then we consider
// the body of this element.
cursor += 1;
skipWhitespace();
if(content[cursor] == '<') {
// Do not do anything; we will do this in the main loop!
XmlElement parent = elements[node];
parent.elements.Add(id);
node = id;
return;
}
// Otherwise, we will keep on going until we reach the ending '>'
int left = cursor;
while(content[cursor] != '<') {
cursor++;
}
// Once we do, just set the body!
// We can't deliver any other nodes, so we will early exit.
element.body = data.Substring(left, cursor - left);
// </type>
cursor += 3 + type.Length;
}
private void parseElement() {
if(content[cursor] == '/') {
parseClosingElement();
} else {
parseNewElement();
}
}
public void parse() {
// Our parser
while(cursor < length) {
skipWhitespace();
cursor++;
parseElement();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment