Skip to content

Instantly share code, notes, and snippets.

@Aetopia
Last active July 15, 2025 10:00
Show Gist options
  • Select an option

  • Save Aetopia/1c244893a6463983971c00f8fff5af5b to your computer and use it in GitHub Desktop.

Select an option

Save Aetopia/1c244893a6463983971c00f8fff5af5b to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace System.Runtime.Serialization.Json.Linq;
public enum JType { Value, Array, Object }
public sealed partial class JElement
{
public static JElement Parse(string value) => Parse(Encoding.Unicode.GetBytes(value));
public static JElement Parse(Stream value)
{
using var reader = JsonReaderWriterFactory.CreateJsonReader(value, XmlDictionaryReaderQuotas.Max);
return new(XElement.Load(reader));
}
public static JElement Parse(byte[] value)
{
using var reader = JsonReaderWriterFactory.CreateJsonReader(value, XmlDictionaryReaderQuotas.Max);
return new(XElement.Load(reader));
}
}
public sealed partial class JElement
{
static JType GetTypeFromElement(XElement element) => element.Attribute("type").Value[0] switch
{
'a' => JType.Array,
'o' => JType.Object,
_ => JType.Value
};
static string GetKeyFromElement(XElement element)
{
var name = element.Name;
if (string.IsNullOrWhiteSpace(name.NamespaceName)) return name.LocalName;
return element.Attribute("item").Value;
}
}
public sealed partial class JElement
{
readonly XElement _element;
public readonly string Key;
public readonly JType Type;
JElement(XElement element)
{
_element = element;
Type = GetTypeFromElement(_element);
var parent = _element.Parent;
if (parent is not null && GetTypeFromElement(parent) != JType.Array)
Key = GetKeyFromElement(_element);
}
public override string ToString()
{
using MemoryStream stream = new();
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.Unicode))
new XElement(_element) { Name = "root" }.WriteTo(writer);
return Encoding.Unicode.GetString(stream.ToArray());
}
}
public sealed partial class JElement
{
public string Value()
{
if (Type != JType.Value) throw new NotImplementedException();
return _element.Value;
}
public T Value<T>() => (T)Convert.ChangeType(Value(), typeof(T), CultureInfo.InvariantCulture);
}
public sealed partial class JElement
{
public JElement this[string key]
{
get
{
if (Type != JType.Object)
throw new NotImplementedException();
foreach (var element in _element.Elements())
if (GetKeyFromElement(element) == key)
return new(element);
throw new KeyNotFoundException();
}
}
public JElement this[int index]
{
get
{
if (Type != JType.Array) throw new NotImplementedException();
return new(_element.Elements().ElementAtOrDefault(index) ?? throw new IndexOutOfRangeException());
}
}
}
public sealed partial class JElement : IEnumerable<JElement>
{
public IEnumerator<JElement> GetEnumerator()
{
if (Type == JType.Value) throw new NotImplementedException();
foreach (var element in _element.Elements())
yield return new(element);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment