From 0fa0ff6a888c9f9a544566974829976e42a5e15e Mon Sep 17 00:00:00 2001 From: schnulller Date: Sun, 26 Jun 2022 22:48:25 +0200 Subject: [PATCH] Added collection classes. Will not do extra collection for subcomments rn. --- HaWeb/Controllers/BriefeContoller.cs | 2 +- HaWeb/Models/CollectedItem.cs | 21 ++- HaWeb/Models/ItemsCollection.cs | 45 +++-- .../XMLCollections/BacklinkCollection.cs | 48 ++++++ .../XMLCollections/CommentCollections.cs | 160 ++++++++++++++++++ .../Settings/XMLCollections/EditCollection.cs | 21 +++ .../XMLCollections/LetterCollection.cs | 21 +++ .../XMLCollections/MarginalCollection.cs | 41 +++++ .../Settings/XMLCollections/MetaCollection.cs | 21 +++ .../XMLCollections/ReferenceCollections.cs | 57 +++++++ .../XMLCollections/TraditionCollection.cs | 21 +++ HaWeb/Settings/XMLRoots/CommentRoot.cs | 29 ---- HaWeb/Settings/XMLRoots/DescriptionsRoot.cs | 21 +-- HaWeb/Settings/XMLRoots/DocumentRoot.cs | 19 --- HaWeb/Settings/XMLRoots/EditsRoot.cs | 21 +-- HaWeb/Settings/XMLRoots/MarginalsRoot.cs | 19 --- HaWeb/Settings/XMLRoots/ReferencesRoot.cs | 22 +-- HaWeb/Settings/XMLRoots/TraditionsRoot.cs | 21 +-- HaWeb/Views/Briefe/Index.cshtml | 2 +- HaWeb/XMLParser/IXMLCollection.cs | 24 +++ HaWeb/XMLParser/IXMLRoot.cs | 18 -- HaWeb/XMLParser/XMLService.cs | 62 ++++--- 22 files changed, 490 insertions(+), 226 deletions(-) create mode 100644 HaWeb/Settings/XMLCollections/BacklinkCollection.cs create mode 100644 HaWeb/Settings/XMLCollections/CommentCollections.cs create mode 100644 HaWeb/Settings/XMLCollections/EditCollection.cs create mode 100644 HaWeb/Settings/XMLCollections/LetterCollection.cs create mode 100644 HaWeb/Settings/XMLCollections/MarginalCollection.cs create mode 100644 HaWeb/Settings/XMLCollections/MetaCollection.cs create mode 100644 HaWeb/Settings/XMLCollections/ReferenceCollections.cs create mode 100644 HaWeb/Settings/XMLCollections/TraditionCollection.cs create mode 100644 HaWeb/XMLParser/IXMLCollection.cs diff --git a/HaWeb/Controllers/BriefeContoller.cs b/HaWeb/Controllers/BriefeContoller.cs index bfaf001..1be9dcc 100644 --- a/HaWeb/Controllers/BriefeContoller.cs +++ b/HaWeb/Controllers/BriefeContoller.cs @@ -70,7 +70,7 @@ public class Briefecontroller : Controller { else model.ParsedMarginals = parsedLetter.ParsedMarginals; if (parsedLetter.Startline != "-1" && parsedLetter.Startline != "1" && model.MetaData.ParsedZHString != null) model.MetaData.ParsedZHString += " / " + parsedLetter.Startline; - if (model.ParsedText == null || String.IsNullOrWhiteSpace(model.ParsedText)) + if (String.IsNullOrWhiteSpace(model.ParsedText)) model.MetaData.HasText = false; } diff --git a/HaWeb/Models/CollectedItem.cs b/HaWeb/Models/CollectedItem.cs index 8058e3e..1dc04fa 100644 --- a/HaWeb/Models/CollectedItem.cs +++ b/HaWeb/Models/CollectedItem.cs @@ -1,3 +1,5 @@ +using System.Reflection.Emit; +using System.Collections; namespace HaWeb.Models; using HaWeb.SearchHelpers; using HaWeb.XMLParser; @@ -5,25 +7,30 @@ using System.Xml.Linq; public class CollectedItem : ISearchable { public string Index { get; private set; } - public string Collection { get; private set; } public string? SearchText { get; private set; } - public Dictionary? Fields { get; private set; } + public IDictionary? Fields { get; private set; } public XElement ELement { get; private set; } - public IXMLRoot Root { get; private set; } + public IXMLCollection Collection { get; private set; } public CollectedItem( string index, XElement element, - IXMLRoot root, - string collection, - Dictionary? fields, + IXMLCollection collection, + IDictionary? fields, string? searchtext = null ) { this.Index = index; this.SearchText = searchtext; this.Collection = collection; - this.Root = root; this.ELement = element; this.Fields = fields; } + + public string? this[string v] { + get { + if (Fields != null && Fields.ContainsKey(v)) + return Fields[v]; + return null; + } + } } \ No newline at end of file diff --git a/HaWeb/Models/ItemsCollection.cs b/HaWeb/Models/ItemsCollection.cs index d77438d..c64ad14 100644 --- a/HaWeb/Models/ItemsCollection.cs +++ b/HaWeb/Models/ItemsCollection.cs @@ -3,45 +3,40 @@ using HaWeb.XMLParser; public class ItemsCollection { public string Name { get; private set; } - public Dictionary Items { get; private set; } - public bool Searchable { get; private set; } - public IXMLRoot Root { get; private set; } - public Func, Dictionary>?>? GroupingsGeneration { get; private set; } - public Func, Dictionary>?>? SortingsGeneration { get; private set; } + public IDictionary Items { get; private set; } + public IXMLCollection Collection { get; private set; } - public Dictionary>? Groupings { get; private set; } - public Dictionary>? Sortings { get; private set; } + public IDictionary>? Groupings { get; private set; } + public IDictionary>? Sortings { get; private set; } public ItemsCollection( string name, - bool searchable, - IXMLRoot root, - Func, Dictionary>?>? groupingsFunc = null, - Func, Dictionary>?>? sortingsFunc = null + IXMLCollection collection ) { this.Name = name; - this.Searchable = searchable; - this.Root = root; - this.GroupingsGeneration = groupingsFunc; - this.SortingsGeneration = sortingsFunc; + this.Collection = collection; this.Items = new Dictionary(); } public void GenerateGroupings( - Func, Dictionary>?>? groupingsFunc = null + Func, Dictionary>?>? groupingsFunc = null ) { - if (groupingsFunc != null) - this.GroupingsGeneration = groupingsFunc; - if (this.GroupingsGeneration != null && this.Items.Any()) - this.Groupings = GroupingsGeneration(this.Items.Values.ToList()); + if (groupingsFunc != null) { + this.Groupings = groupingsFunc(this.Items.Values.ToList()); + return; + } + if (Collection.GroupingsGeneration != null && this.Items.Any()) + this.Groupings = Collection.GroupingsGeneration(this.Items.Values.ToList()); } public void GenerateSortings( - Func, Dictionary>?>? sortingsFunc = null + Func, Dictionary>?>? sortingsFunc = null ) { - if (sortingsFunc != null) - this.SortingsGeneration = sortingsFunc; - if (this.SortingsGeneration != null && this.Items.Any()) - this.Sortings = SortingsGeneration(this.Items.Values.ToList()); + if (sortingsFunc != null) { + this.Sortings = sortingsFunc(this.Items.Values.ToList()); + return; + } + if (Collection.SortingsGeneration != null && this.Items.Any()) + this.Sortings = Collection.SortingsGeneration(this.Items.Values.ToList()); } } diff --git a/HaWeb/Settings/XMLCollections/BacklinkCollection.cs b/HaWeb/Settings/XMLCollections/BacklinkCollection.cs new file mode 100644 index 0000000..bc7d34a --- /dev/null +++ b/HaWeb/Settings/XMLCollections/BacklinkCollection.cs @@ -0,0 +1,48 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class BackLinkCollection : HaWeb.XMLParser.IXMLCollection { + private static readonly Random _random = new Random(); + public string Key { get; } = "backlinks"; + public string[] xPath { get; } = new string[] { "/opus/data/marginalien/marginal/link", "/opus/marginalien/marginal/link" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var margid = (string?)elem.Ancestors("marginal").First().Attribute("index"); + if (String.IsNullOrWhiteSpace(margid)) return null; + return margid + _random.Next().ToString(); + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var marg = element.Ancestors("marginal").First(); + var index = (string?)marg.Attribute("index"); + var letter = (string?)marg.Attribute("letter"); + var page = (string?)marg.Attribute("page"); + var line = (string?)marg.Attribute("line"); + var refere = (string?)element.Attribute("ref"); + var subref = (string?)element.Attribute("subref"); + if (index == null || letter == null || (refere == null && subref == null)) return null; + if (subref != null) res.Add("ref", subref); + else res.Add("ref", refere!); + res.Add("index", index); + res.Add("letter", letter); + if(page != null) res.Add("page", page); + if(line != null) res.Add("line", line); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var refs = items.Where(x => x["ref"] != null); + if (refs == null || !refs.Any()) return null; + res.Add("ref", refs.ToLookup(x => x["ref"])!); + return res; + } +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/CommentCollections.cs b/HaWeb/Settings/XMLCollections/CommentCollections.cs new file mode 100644 index 0000000..4505033 --- /dev/null +++ b/HaWeb/Settings/XMLCollections/CommentCollections.cs @@ -0,0 +1,160 @@ +using System.Xml; +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class BibleCommentCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "bible-comments"; + public string[] xPath { get; } = new string[] { "/opus/data/kommentare/kommcat[@value='bibel']/kommentar", "/opus/kommentare/kommcat[@value='bibel']/kommentar" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = GetLookups; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = false; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("id"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var lemma = element.Descendants("lemma"); + if (!lemma.Any() || String.IsNullOrWhiteSpace(lemma.First().Value)) return null; + res.Add("lemma", lemma.First().Value); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var lemmas = items.Where(x => !String.IsNullOrWhiteSpace(x.Index)); + if (lemmas != null && lemmas.Any()) + res.Add("lemma", lemmas.ToLookup(x => x.Index.Substring(0, 1).ToUpper())); + // If we use lemmas + // var lemmas = items.Where(x => x.Fields != null && x.Fields.ContainsKey("lemma")); + // if (lemmas != null && lemmas.Any()) + // res.Add("lemma", lemmas.ToLookup(x => x.Fields["lemma"][0].First().ToString())); + if (!res.Any()) return null; + return res; + } +} + +public class EditionCommentCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "edition-comments"; + public string[] xPath { get; } = new string[] { "/opus/data/kommentare/kommcat[@value='editionen']/kommentar", "/opus/kommentare/kommcat[@value='editionen']/kommentar" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = GetLookups; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("id"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var lemma = element.Descendants("lemma"); + if (!lemma.Any() || String.IsNullOrWhiteSpace(lemma.First().Value)) return null; + res.Add("lemma", lemma.First().Value); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var lemmas = items.Where(x => !String.IsNullOrWhiteSpace(x.Index)); + if (lemmas != null && lemmas.Any()) + res.Add("lemma", lemmas.ToLookup(x => x.Index.Substring(0, 1).ToUpper())); + // If we use lemmas + // var lemmas = items.Where(x => x.Fields != null && x.Fields.ContainsKey("lemma")); + // if (lemmas != null && lemmas.Any()) + // res.Add("lemma", lemmas.ToLookup(x => x.Fields["lemma"][0].First().ToString())); + if (!res.Any()) return null; + return res; + } +} + +public class RegisterCommentCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "register-comments"; + public string[] xPath { get; } = new string[] { "/opus/data/kommentare/kommcat[@value='neuzeit']/kommentar", "/opus/kommentare/kommcat[@value='neuzeit']/kommentar" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = GetLookups; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("id"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var lemma = element.Descendants("lemma"); + if (!lemma.Any() || String.IsNullOrWhiteSpace(lemma.First().Value)) return null; + res.Add("lemma", lemma.First().Value); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var lemmas = items.Where(x => !String.IsNullOrWhiteSpace(x.Index)); + if (lemmas != null && lemmas.Any()) + res.Add("lemma", lemmas.ToLookup(x => x.Index.Substring(0, 1).ToUpper())); + // If we use lemmas + // var lemmas = items.Where(x => x.Fields != null && x.Fields.ContainsKey("lemma")); + // if (lemmas != null && lemmas.Any()) + // res.Add("lemma", lemmas.ToLookup(x => x.Fields["lemma"][0].First().ToString())); + if (!res.Any()) return null; + return res; + } +} + +public class ForschungCommentCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "forschung-comments"; + public string[] xPath { get; } = new string[] { "/opus/data/kommentare/kommcat[@value='forschung']/kommentar", "/opus/kommentare/kommcat[@value='forschung']/kommentar" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = GetLookups; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("id"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var lemma = element.Descendants("lemma"); + if (!lemma.Any() || String.IsNullOrWhiteSpace(lemma.First().Value)) return null; + res.Add("lemma", lemma.First().Value); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var lemmas = items.Where(x => !String.IsNullOrWhiteSpace(x.Index)); + if (lemmas != null && lemmas.Any()) + res.Add("lemma", lemmas.ToLookup(x => x.Index.Substring(0, 1).ToUpper())); + // If we use lemmas + // var lemmas = items.Where(x => x.Fields != null && x.Fields.ContainsKey("lemma")); + // if (lemmas != null && lemmas.Any()) + // res.Add("lemma", lemmas.ToLookup(x => x.Fields["lemma"][0].First().ToString())); + if (!res.Any()) return null; + return res; + } +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/EditCollection.cs b/HaWeb/Settings/XMLCollections/EditCollection.cs new file mode 100644 index 0000000..81f80ae --- /dev/null +++ b/HaWeb/Settings/XMLCollections/EditCollection.cs @@ -0,0 +1,21 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class EditCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "edits"; + public string[] xPath { get; } = new string[] { "/opus/edits/editreason", "/opus/data/edits/editreason" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/LetterCollection.cs b/HaWeb/Settings/XMLCollections/LetterCollection.cs new file mode 100644 index 0000000..1c39a26 --- /dev/null +++ b/HaWeb/Settings/XMLCollections/LetterCollection.cs @@ -0,0 +1,21 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class LetterCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "letters"; + public string[] xPath { get; } = new string[] { "/opus/data/document/letterText", "/opus/document/letterText" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/MarginalCollection.cs b/HaWeb/Settings/XMLCollections/MarginalCollection.cs new file mode 100644 index 0000000..e5f7bc3 --- /dev/null +++ b/HaWeb/Settings/XMLCollections/MarginalCollection.cs @@ -0,0 +1,41 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class MarginalCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "marginals"; + public string[] xPath { get; } = new string[] { "/opus/data/marginalien/marginal", "/opus/marginalien/marginal" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = GetDataFields; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + else return null; + }; + + public static IDictionary? GetDataFields(XElement element) { + var res = new Dictionary(); + var letter = (string?)element.Attribute("letter"); + var page = (string?)element.Attribute("page"); + var line = (string?)element.Attribute("line"); + if (letter == null || page == null || line == null) return null; + res.Add("letter", letter); + res.Add("page", page); + res.Add("line", line); + return res; + } + + public static IDictionary>? GetLookups(IEnumerable items) { + var res = new Dictionary>(); + var letters = items.Where(x => x["letter"] != null && x["letter"]!.Count() > 0); + if (letters == null || !letters.Any()) return null; + res.Add("letter", letters.ToLookup(x => x["letter"]!)); + return res; + } +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/MetaCollection.cs b/HaWeb/Settings/XMLCollections/MetaCollection.cs new file mode 100644 index 0000000..49c8ba3 --- /dev/null +++ b/HaWeb/Settings/XMLCollections/MetaCollection.cs @@ -0,0 +1,21 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class MetaCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "metas"; + public string[] xPath { get; } = new string[] { "/opus/descriptions/letterDesc", "/opus/data/descriptions/letterDesc" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = false; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("ref"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + return null; + }; +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/ReferenceCollections.cs b/HaWeb/Settings/XMLCollections/ReferenceCollections.cs new file mode 100644 index 0000000..f94be4c --- /dev/null +++ b/HaWeb/Settings/XMLCollections/ReferenceCollections.cs @@ -0,0 +1,57 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class HandPersonCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "handpersons"; + public string[] xPath { get; } = new string[] { "/opus/data/definitions/handDefs/handDef", "/opus/definitions/handDefs/handDef" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = false; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + return null; + }; +} + +public class PersonCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "persons"; + public string[] xPath { get; } = new string[] { "/opus/data/definitions/personDefs/personDef", "/opus/definitions/personDefs/personDef" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = false; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + return null; + }; +} + +public class LocationCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "locations"; + public string[] xPath { get; } = new string[] { "/opus/data/definitions/locationDefs/locationDef", "/opus/definitions/locationDefs/locationDef" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = false; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("index"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + return null; + }; +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLCollections/TraditionCollection.cs b/HaWeb/Settings/XMLCollections/TraditionCollection.cs new file mode 100644 index 0000000..6886e72 --- /dev/null +++ b/HaWeb/Settings/XMLCollections/TraditionCollection.cs @@ -0,0 +1,21 @@ +namespace HaWeb.Settings.XMLCollections; +using HaWeb.Models; +using System.Xml.Linq; + +public class TraditionCollection : HaWeb.XMLParser.IXMLCollection { + public string Key { get; } = "traditions"; + public string[] xPath { get; } = new string[] { "/opus/data/traditions/letterTradition", "/opus/traditions/letterTradition" }; + public Func GenerateKey { get; } = GetKey; + public Func?>? GenerateDataFields { get; } = null; + public Func, IDictionary>?>? GroupingsGeneration { get; } = null; + public Func, IDictionary>?>? SortingsGeneration { get; } = null; + public HaWeb.XMLParser.IXMLCollection[]? SubCollections { get; } = null; + public bool Searchable { get; } = true; + + public static Func GetKey { get; } = (elem) => { + var index = elem.Attribute("ref"); + if (index != null && !String.IsNullOrWhiteSpace(index.Value)) + return index.Value; + return null; + }; +} \ No newline at end of file diff --git a/HaWeb/Settings/XMLRoots/CommentRoot.cs b/HaWeb/Settings/XMLRoots/CommentRoot.cs index e9ffe8b..bb9f772 100644 --- a/HaWeb/Settings/XMLRoots/CommentRoot.cs +++ b/HaWeb/Settings/XMLRoots/CommentRoot.cs @@ -7,41 +7,12 @@ public class CommentRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Register"; public string Prefix { get; } = "register"; public string[] XPathContainer { get; } = { ".//data//kommentare/kommcat", ".//kommentare/kommcat" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("comments-register", "/opus/data/kommentare/kommcat[@value='neuzeit']/kommentar", GetKey, null, null, null, true), - ("comments-register", "/opus/kommentare/kommcat[@value='neuzeit']/kommentar", GetKey, null, null, null, true), - ("subcomments-register", "/opus/data/kommentare/kommcat[@value='neuzeit']/kommentar/subsection", GetKey, null, null, null, true), - ("subcomments-register", "/opus/kommentare/kommcat[@value='neuzeit']/kommentar/subsection", GetKey, null, null, null, true), - ("comments-edition", "/opus/data/kommentare/kommcat[@value='editionen']/kommentar", GetKey, null, null, null, true), - ("comments-edition", "/opus/kommentare/kommcat[@value='editionen']/kommentar", GetKey, null, null, null, true), - ("comments-forschung", "/opus/data/kommentare/kommcat[@value='forschung']/kommentar", GetKey, null, null, null, true), - ("comments-forschung", "/opus/kommentare/kommcat[@value='forschung']/kommentar", GetKey, null, null, null, true), - ("comments-bibel", "/opus/data/kommentare/kommcat[@value='bibel']/kommentar", GetKey, null, null, null, false), - ("comments-bibel", "/opus/kommentare/kommcat[@value='bibel']/kommentar", GetKey, null, null, null, false), - ("subcomments-bibel", "/opus/data/kommentare/kommcat[@value='bibel']/kommentar/subsection", GetKey, null, null, null, false), - ("subcomments-bibel", "/opus/kommentare/kommcat[@value='bibel']/kommentar/subsection", GetKey, null, null, null, false), - }; public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "kommentar") return true; else return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("id"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - else return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/DescriptionsRoot.cs b/HaWeb/Settings/XMLRoots/DescriptionsRoot.cs index 3b8eb5e..c2d180d 100644 --- a/HaWeb/Settings/XMLRoots/DescriptionsRoot.cs +++ b/HaWeb/Settings/XMLRoots/DescriptionsRoot.cs @@ -7,31 +7,12 @@ public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Metadaten"; public string Prefix { get; } = "metadaten"; public string[] XPathContainer { get; } = { ".//data/descriptions", ".//descriptions" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("metas", "/opus/descriptions/letterDesc", GetKey, null, null, null, false), - ("metas", "/opus/data/descriptions/letterDesc", GetKey, null, null, null, false) - }; - + public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "letterDesc") return true; return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("ref"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/DocumentRoot.cs b/HaWeb/Settings/XMLRoots/DocumentRoot.cs index 8eb9774..134863c 100644 --- a/HaWeb/Settings/XMLRoots/DocumentRoot.cs +++ b/HaWeb/Settings/XMLRoots/DocumentRoot.cs @@ -8,31 +8,12 @@ public class DocumentRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Brieftext"; public string Prefix { get; } = "brieftext"; public string[] XPathContainer { get; } = { ".//data/document", ".//document" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("letters", "/opus/data/document/letterText", GetKey, null, null, null, true), - ("letters", "/opus/document/letterText", GetKey, null, null, null, true) - }; public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "letterText") return true; else return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("index"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - else return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/EditsRoot.cs b/HaWeb/Settings/XMLRoots/EditsRoot.cs index d26f0dd..0c867af 100644 --- a/HaWeb/Settings/XMLRoots/EditsRoot.cs +++ b/HaWeb/Settings/XMLRoots/EditsRoot.cs @@ -7,31 +7,12 @@ public class EditsRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Texteingriffe"; public string Prefix { get; } = "texteingriffe"; public string[] XPathContainer { get; } = { ".//data/edits", ".//edits" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("edits", "/data/edits/editreason", GetKey, null, null, null, true), - ("edits", "/edits/editreason", GetKey, null, null, null, true) - }; - + public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "editreason") return true; else return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("index"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - else return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/MarginalsRoot.cs b/HaWeb/Settings/XMLRoots/MarginalsRoot.cs index d714358..b9442a3 100644 --- a/HaWeb/Settings/XMLRoots/MarginalsRoot.cs +++ b/HaWeb/Settings/XMLRoots/MarginalsRoot.cs @@ -7,31 +7,12 @@ public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Stellenkommentar"; public string Prefix { get; } = "stellenkommentar"; public string[] XPathContainer { get; } = { ".//data/marginalien", ".//marginalien" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("marginals", "/data/marginalien/marginal", GetKey, null, null, null, true), - ("marginals", "/marginalien/marginal", GetKey, null, null, null, true) - }; public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "marginal") return true; else return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("index"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - else return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/ReferencesRoot.cs b/HaWeb/Settings/XMLRoots/ReferencesRoot.cs index 1abac90..5da26fe 100644 --- a/HaWeb/Settings/XMLRoots/ReferencesRoot.cs +++ b/HaWeb/Settings/XMLRoots/ReferencesRoot.cs @@ -7,33 +7,13 @@ public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Personen / Orte"; public string Prefix { get; } = "personenorte"; public string[] XPathContainer { get; } = { ".//data/definitions", ".//definitions" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("person-definitions", "/opus/data/definitions/personDefs/personDef", GetKey, null, null, null, false), - ("person-definitions", "/opus/definitions/personDefs/personDef", GetKey, null, null, null, false), - ("hand-definitions", "/opus/data/definitions/handDefs/handDef", GetKey, null, null, null, false), - ("hand-definitions", "/opus/definitions/handDefs/handDef", GetKey, null, null, null, false), - ("location-definitions", "/opus/data/definitions/locationDefs/locationDef", GetKey, null, null, null, false), - ("location-definitions", "/opus/definitions/locationDefs/locationDef", GetKey, null, null, null, false) - }; - + public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "personDefs" || elem.Name == "structureDefs" || elem.Name == "handDefs" || elem.Name == "locationDefs") return true; return false; }; - public static Func GetKey { get; } = (elem) => { - return elem.Attribute("index") != null ? elem.Attribute("index")!.Value : null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Settings/XMLRoots/TraditionsRoot.cs b/HaWeb/Settings/XMLRoots/TraditionsRoot.cs index 8f34bee..927df7e 100644 --- a/HaWeb/Settings/XMLRoots/TraditionsRoot.cs +++ b/HaWeb/Settings/XMLRoots/TraditionsRoot.cs @@ -7,31 +7,12 @@ public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot { public string Type { get; } = "Überlieferung"; public string Prefix { get; } = "ueberlieferung"; public string[] XPathContainer { get; } = { ".//data/traditions", ".//traditions" }; - public ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } = { - ("tradition", "/opus/data/traditions/letterTradition", GetKey, null, null, null, true), - ("tradition", "/opus/traditions/letterTradition", GetKey, null, null, null, true) - }; - + public Predicate IsCollectedObject { get; } = (elem) => { if (elem.Name == "letterTradition") return true; else return false; }; - public static Func GetKey { get; } = (elem) => { - var index = elem.Attribute("ref"); - if (index != null && !String.IsNullOrWhiteSpace(index.Value)) - return index.Value; - return null; - }; - public List<(string, string?)>? GenerateFields(XMLRootDocument document) { return null; } diff --git a/HaWeb/Views/Briefe/Index.cshtml b/HaWeb/Views/Briefe/Index.cshtml index d2b2c57..793e1c4 100644 --- a/HaWeb/Views/Briefe/Index.cshtml +++ b/HaWeb/Views/Briefe/Index.cshtml @@ -16,7 +16,7 @@ @await Html.PartialAsync("/Views/Shared/_LetterHead.cshtml", (Model.MetaData, false))
- @if (Model.ParsedText != null && !String.IsNullOrWhiteSpace(Model.ParsedText)) + @if (!String.IsNullOrWhiteSpace(Model.ParsedText)) { Brieftext @if (Model.ParsedMarginals != null) diff --git a/HaWeb/XMLParser/IXMLCollection.cs b/HaWeb/XMLParser/IXMLCollection.cs new file mode 100644 index 0000000..6fbd4da --- /dev/null +++ b/HaWeb/XMLParser/IXMLCollection.cs @@ -0,0 +1,24 @@ +namespace HaWeb.XMLParser; +using HaWeb.Models; +using System.Xml.Linq; + +public interface IXMLCollection { + // Collections of Elements to be created a Hamann File Root + // Key: the key under which the element(s) will be filed + // xPath: (absolute, realtive if subelement) XPaths to the element(s) + // GenerateKey: How to extract an identifier for the single element in the collection + // GenerateDataFields: Generate a dict of data associated with each of the collected Elements input: XElement output: Dictonary + // GroupingsGeneration: datafields by which dictorary-like groups should be held in memory input: List output: Dictonary> + // SortingsGeneration: datafields by which a sorting should be held in memory input: List output: ordered List + // SubCollections to be created in this element + // Searchable: Will the element be indexed for full-text-search? + + abstract string Key { get; } + abstract string[] xPath { get; } + abstract Func GenerateKey { get; } + abstract Func?>? GenerateDataFields { get; } + abstract Func, IDictionary>?>? GroupingsGeneration { get; } + abstract Func, IDictionary>?>? SortingsGeneration { get; } + abstract IXMLCollection[]? SubCollections { get; } + abstract bool Searchable { get; } +} \ No newline at end of file diff --git a/HaWeb/XMLParser/IXMLRoot.cs b/HaWeb/XMLParser/IXMLRoot.cs index 015d2a8..43b41d6 100644 --- a/HaWeb/XMLParser/IXMLRoot.cs +++ b/HaWeb/XMLParser/IXMLRoot.cs @@ -13,24 +13,6 @@ public interface IXMLRoot { // XPaths to determine if container is present public abstract string[] XPathContainer { get; } - // Collections of Elements to be created from this Root - // Key: the key under which the element(s) will be files - // xPath: the (absolute) XPath to the element(s) - // Searchable: Will the element be indexed for full-text-search? - // GenerateKey: How to extrect an identifier for the single element in the collection - // GenerateDataFields: Generate a dict of data associated with each of the collected Elements input: XElement output: Dictonary - // GroupingsGeneration: datafields by which dictorary-like groups should be held in memory input: List output: Dictonary> - // SortingsGeneration: datafields by which a sorting should be held in memory input: List output: ordered List - public abstract ( - string Key, - string xPath, - Func GenerateKey, - Func?>? GenerateDataFields, - Func, Dictionary>?>? GroupingsGeneration, - Func, Dictionary>?>? SortingsGeneration, - bool Searchable - )[]? Collections { get; } - // Determines child objects to be collected // (deprecated see collections above; only used internally) public abstract Predicate IsCollectedObject { get; } diff --git a/HaWeb/XMLParser/XMLService.cs b/HaWeb/XMLParser/XMLService.cs index 438ae44..3623db5 100644 --- a/HaWeb/XMLParser/XMLService.cs +++ b/HaWeb/XMLParser/XMLService.cs @@ -12,6 +12,7 @@ using HaXMLReader.Interfaces; public class XMLService : IXMLService { private Dictionary? _Used; private Dictionary? _Roots; + private Dictionary? _Collections; private Stack>? _InProduction; @@ -20,15 +21,25 @@ public class XMLService : IXMLService { public XMLService() { // Getting all classes which implement IXMLRoot for possible document endpoints - var types = _GetAllTypesThatImplementInterface().ToList(); - types.ForEach( x => { + var roottypes = _GetAllTypesThatImplementInterface().ToList(); + roottypes.ForEach( x => { if (this._Roots == null) this._Roots = new Dictionary(); var instance = (IXMLRoot)Activator.CreateInstance(x)!; if (instance != null) this._Roots.Add(instance.Prefix, instance); }); + var collectiontypes = _GetAllTypesThatImplementInterface().ToList(); + collectiontypes.ForEach( x => { + if (this._Collections == null) this._Collections = new Dictionary(); + var instance = (IXMLCollection)Activator.CreateInstance(x)!; + if (instance != null) this._Collections.Add(instance.Key, instance); + }); + if (_Roots == null || !_Roots.Any()) throw new Exception("No classes for upload endpoints were found!"); + + if (_Collections == null || !_Collections.Any()) + throw new Exception("No classes for object collection were found!"); } public IXMLRoot? GetRoot(string name) { @@ -66,33 +77,32 @@ public class XMLService : IXMLService { int startingSize = 2909; int startingSizeAllCollections = 23; var ret = new ConcurrentDictionary(concurrencyLevel, startingSizeAllCollections); - foreach (var root in _Roots) { - if (root.Value.Collections != null) - foreach (var coll in root.Value.Collections) { - var elem = document.XPathSelectElements(coll.xPath); - if (elem != null && elem.Any()) { - var items = new ConcurrentDictionary(concurrencyLevel, startingSize); - Parallel.ForEach(elem, (e) => { - var k = coll.GenerateKey(e); - if (k != null) { - var searchtext = coll.Searchable ? - StringHelpers.NormalizeWhiteSpace(e.ToString(), ' ', false) : - null; - var datafileds = coll.GenerateDataFields != null ? - coll.GenerateDataFields(e) : - null; - items[k] = new CollectedItem(k, e, root.Value, coll.Key, datafileds, searchtext); - } - }); - if (items.Any()) { - if (!ret.ContainsKey(coll.Key)) - ret[coll.Key] = new ItemsCollection(coll.Key, coll.Searchable, root.Value, coll.GroupingsGeneration, coll.SortingsGeneration); - foreach (var item in items) - ret[coll.Key].Items.Add(item.Key, item.Value); + + if (_Collections != null) + foreach (var coll in _Collections) { + var elem = coll.Value.xPath.Aggregate(new List(), (x, y) => { x.AddRange(document.XPathSelectElements(y).ToList()); return x; } ); + if (elem != null && elem.Any()) { + var items = new ConcurrentDictionary(concurrencyLevel, startingSize); + Parallel.ForEach(elem, (e) => { + var k = coll.Value.GenerateKey(e); + if (k != null) { + var searchtext = coll.Value.Searchable ? + StringHelpers.NormalizeWhiteSpace(e.ToString(), ' ', false) : + null; + var datafileds = coll.Value.GenerateDataFields != null ? + coll.Value.GenerateDataFields(e) : + null; + items[k] = new CollectedItem(k, e, coll.Value, datafileds, searchtext); } + }); + if (items.Any()) { + if (!ret.ContainsKey(coll.Key)) + ret[coll.Key] = new ItemsCollection(coll.Key, coll.Value); + foreach (var item in items) + ret[coll.Key].Items.Add(item.Key, item.Value); } } - } + } if (ret.Any()) { Parallel.ForEach(ret, (collection) => {