69 lines
2.4 KiB
C#
69 lines
2.4 KiB
C#
|
|
using aeqw89.DataKeys;
|
|
using HtmlAgilityPack;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Beam.Dynamic {
|
|
public class Binding(DataKey<Binding> key) : IKeyed<Binding> {
|
|
public Binding(string key) : this(new DataKey<Binding>(key)) { }
|
|
public Binding() : this("") { }
|
|
|
|
[JsonRequired]
|
|
public DataKey<Binding> Key { get; set; } = key;
|
|
[JsonRequired]
|
|
public BindingType Type { get; set; }
|
|
|
|
public string? ArrayDelimiters { get; set; }
|
|
public string? XPath { get; set; }
|
|
public string? CssPath { get; set; }
|
|
private IDataProvider? Provider_;
|
|
public IDataProvider? Provider {
|
|
get => Provider_;
|
|
set {
|
|
if (value is null)
|
|
return;
|
|
if (value is not IDataProvider)
|
|
throw new InvalidOperationException();
|
|
var constructor = value.GetType().GetConstructor([]);
|
|
if (!constructor?.IsPublic ?? true)
|
|
throw new InvalidOperationException();
|
|
Provider_ = value;
|
|
}
|
|
}
|
|
|
|
public HtmlNode? ResolveNode(HtmlDocument doc) {
|
|
if (XPath is not null)
|
|
return doc.DocumentNode.SelectSingleNode(XPath);
|
|
if (CssPath is not null)
|
|
return doc.DocumentNode.ThenByClasses(CssPath.Split('/'));
|
|
if (Provider is not null)
|
|
return Provider.GetNode(doc);
|
|
return null;
|
|
}
|
|
|
|
public string ResolveString(HtmlDocument doc) {
|
|
if (XPath is not null)
|
|
return doc.DocumentNode.SelectSingleNode(XPath)?.InnerText ?? "";
|
|
if (CssPath is not null)
|
|
return doc.DocumentNode.ThenByClasses(CssPath.Split('/'))?.InnerText ?? "";
|
|
if (Provider is not null)
|
|
return Provider.Get(doc);
|
|
return "";
|
|
}
|
|
|
|
public string[] ResolveArray(HtmlDocument doc) {
|
|
if (Type is not BindingType.Array)
|
|
return [];
|
|
var str = ResolveString(doc);
|
|
return str.Split(ArrayDelimiters);
|
|
}
|
|
|
|
public dynamic? Resolve(HtmlDocument doc) => Type switch {
|
|
BindingType.Single => ResolveString(doc),
|
|
BindingType.Array => ResolveArray(doc),
|
|
BindingType.UseProvider => Provider?.Get(doc),
|
|
_ => null
|
|
};
|
|
}
|
|
}
|