Last active
July 15, 2025 10:00
-
-
Save Aetopia/1c244893a6463983971c00f8fff5af5b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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