using Beam.Abstractions; using HtmlAgilityPack; namespace Beam.Dynamic; public enum RelationType { Parent, Child, NextSibling, PreviousSibling, } public class RelationalDataProvider : IComposableDataProvider { public RelationType RelationType { get; set; } = RelationType.Parent; public int Distance { get; set; } = 1; public IBinding? Content { get; set; } public HtmlNode? Get(HtmlDocument document) { return Select(document); } public HtmlNode? Get(HtmlNode node) { return Select(node); } public HtmlNode? Select(HtmlDocument doc) { return Select(Content?.Select(doc) ?? doc.DocumentNode); } public HtmlNode? Select(HtmlNode node) { return _Select(node, Distance); } private HtmlNode? _Select(HtmlNode node, int distance = 0) { while (true) { if (distance == 0) return node; node = RelationType switch { RelationType.Parent => node.ParentNode, RelationType.Child => node.FirstChild, RelationType.NextSibling => node.NextSibling, RelationType.PreviousSibling => node.PreviousSibling, _ => throw new NotSupportedException() }; distance = distance - 1; } } }