mirror of
				https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
				synced 2025-10-30 09:45:32 +00:00 
			
		
		
		
	Repaired Bugs in File-Upload. Basic Structure for loading File-Lists
This commit is contained in:
		| @@ -18,6 +18,8 @@ using HaWeb.FileHelpers; | |||||||
| using HaWeb.XMLParser; | using HaWeb.XMLParser; | ||||||
| using HaWeb.Models; | using HaWeb.Models; | ||||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  | using System.Text.Json; | ||||||
|  |  | ||||||
| public class UploadController : Controller | public class UploadController : Controller | ||||||
| { | { | ||||||
| @@ -109,18 +111,36 @@ public class UploadController : Controller | |||||||
|                 if (!ModelState.IsValid || xdocument == null) |                 if (!ModelState.IsValid || xdocument == null) | ||||||
|                     return UnprocessableEntity(ModelState); |                     return UnprocessableEntity(ModelState); | ||||||
|  |  | ||||||
| //// 3. Stage: Is it a Hamann-Document? What kind? | //// 4. Stage: Is it a Hamann-Document? What kind? | ||||||
|                 var docs = _xmlService.ProbeHamannFile(xdocument, ModelState); |                 var docs = _xmlService.ProbeHamannFile(xdocument, ModelState); | ||||||
|                 if (!ModelState.IsValid || docs == null || !docs.Any()) |                 if (!ModelState.IsValid || docs == null || !docs.Any()) | ||||||
|                     return UnprocessableEntity(ModelState); |                     return UnprocessableEntity(ModelState); | ||||||
|                  |                  | ||||||
| //// 5. Stage: Saving the File(s) | //// 5. Stage: Saving the File(s) | ||||||
|                 foreach (var doc in docs) { |                 foreach (var doc in docs) { | ||||||
|                     using (var targetStream = System.IO.File.Create(Path.Combine(_targetFilePath, doc.CreateFilename()))) |                     var type = doc.Prefix; | ||||||
|                         doc.Save(targetStream); |                     var directory = Path.Combine(_targetFilePath, type); | ||||||
|  |                     if (!Directory.Exists(directory)) | ||||||
|  |                         Directory.CreateDirectory(directory); | ||||||
|  |                     var path = Path.Combine(directory, doc.FileName); | ||||||
|  |                     try { | ||||||
|  |                         using (var targetStream = System.IO.File.Create(path)) | ||||||
|  |                             await doc.Save(targetStream, ModelState); | ||||||
|  |                             if (!ModelState.IsValid) return StatusCode(500, ModelState); | ||||||
|  |                     } | ||||||
|  |                     catch (Exception ex) { | ||||||
|  |                         ModelState.AddModelError("Error",  "Speichern der Datei fehlgeschlagen: " + ex.Message); | ||||||
|  |                         return StatusCode(500, ModelState); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 return Created(nameof(UploadController), docs); | // 6. State: Returning Ok, and redirecting  | ||||||
|  |                 JsonSerializerOptions options = new() { | ||||||
|  |                     ReferenceHandler = ReferenceHandler.Preserve | ||||||
|  |                 }; | ||||||
|  |  | ||||||
|  |                 string json = JsonSerializer.Serialize(docs); | ||||||
|  |                 return Created(nameof(UploadController), json); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|            try |            try | ||||||
|   | |||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class CommentRoot : HaWeb.XMLParser.IXMLRoot { | public class CommentRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Register"; |     public string Type { get; } = "Register"; | ||||||
|     public string Container { get; } = "kommcat"; |     public string Prefix { get; } = "register"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data//kommentare/kommcat", ".//kommentare/kommcat" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "kommentar") return true; |         if (elem.Name == "kommentar") return true; | ||||||
| @@ -18,19 +19,27 @@ public class CommentRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         var kat = element.Attribute("value"); |         var kat = element.Attribute("value"); | ||||||
|         if (kat != null && !String.IsNullOrWhiteSpace(kat.Value))  |         if (kat != null && !String.IsNullOrWhiteSpace(kat.Value))  | ||||||
|             return (null, kat.Value); |             return (null, kat.Value); | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         var kommentare = new XElement("kommentare"); | ||||||
|  |         kommentare.AddFirst(element); | ||||||
|  |         opus.AddFirst(kommentare); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot { | public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Metadaten"; |     public string Type { get; } = "Metadaten"; | ||||||
|     public string Container { get; } = "descriptions"; |     public string Prefix { get; } = "metadaten"; | ||||||
|  |     public string[] XPathContainer { get; } = {".//data/descriptions", ".//descriptions" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "letterDesc") return true; |         if (elem.Name == "letterDesc") return true; | ||||||
| @@ -18,16 +19,22 @@ public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class DocumentRoot : HaWeb.XMLParser.IXMLRoot { | public class DocumentRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Brieftext"; |     public string Type { get; } = "Brieftext"; | ||||||
|     public string Container { get; } = "document"; |     public string Prefix { get; } = "brieftext"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data/document", ".//document" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "letterText") return true; |         if (elem.Name == "letterText") return true; | ||||||
| @@ -18,16 +19,22 @@ public class DocumentRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class EditsRoot : HaWeb.XMLParser.IXMLRoot { | public class EditsRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Texteingriffe"; |     public string Type { get; } = "Texteingriffe"; | ||||||
|     public string Container { get; } = "edits"; |     public string Prefix { get; } = "texteingriffe"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data/edits", ".//edits" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "editreason") return true; |         if (elem.Name == "editreason") return true; | ||||||
| @@ -18,16 +19,22 @@ public class EditsRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot { | public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Stellenkommentar"; |     public string Type { get; } = "Stellenkommentar"; | ||||||
|     public string Container { get; } = "marginalien"; |     public string Prefix { get; } = "stellenkommentar"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data/marginalien", ".//marginalien" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "marginal") return true; |         if (elem.Name == "marginal") return true; | ||||||
| @@ -18,16 +19,22 @@ public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot { | public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Personen / Orte"; |     public string Type { get; } = "Personen / Orte"; | ||||||
|     public string Container { get; } = "definitions"; |     public string Prefix { get; } = "personenorte"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data/definitions", ".//definitions" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "personDefs" || elem.Name == "structureDefs" || elem.Name == "handDefs" || elem.Name == "locationDefs") |         if (elem.Name == "personDefs" || elem.Name == "structureDefs" || elem.Name == "handDefs" || elem.Name == "locationDefs") | ||||||
| @@ -16,16 +17,22 @@ public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         return elem.Name.ToString(); |         return elem.Name.ToString(); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -4,7 +4,8 @@ using HaWeb.XMLParser; | |||||||
|  |  | ||||||
| public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot { | public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot { | ||||||
|     public string Type { get; } = "Überlieferung"; |     public string Type { get; } = "Überlieferung"; | ||||||
|     public string Container { get; } = "traditions"; |     public string Prefix { get; } = "ueberlieferung"; | ||||||
|  |     public string[] XPathContainer { get; } = { ".//data/traditions", ".//traditions" }; | ||||||
|  |  | ||||||
|     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { |     public Predicate<XElement> IsCollectedObject { get; } = (elem) => { | ||||||
|         if (elem.Name == "letterTradition") return true; |         if (elem.Name == "letterTradition") return true; | ||||||
| @@ -18,16 +19,22 @@ public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot { | |||||||
|         else return null; |         else return null; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     public List<(string, string)>? GenerateFields(XMLRootDocument document) { |     public List<(string, string?)>? GenerateFields(XMLRootDocument document) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public (string?, string) GenerateIdentificationString(XElement element) { |     public (string?, string?) GenerateIdentificationString(XElement element) { | ||||||
|         return (null, Container); |         return (null, null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { |     public bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public XElement CreateHamannDocument(XElement element) { | ||||||
|  |         var opus = new XElement("opus"); | ||||||
|  |         opus.AddFirst(element); | ||||||
|  |         return opus; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -1,12 +1,16 @@ | |||||||
| namespace HaWeb.XMLParser; | namespace HaWeb.XMLParser; | ||||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||||
|  | using System.Xml.XPath; | ||||||
|  |  | ||||||
| public interface IXMLRoot { | public interface IXMLRoot { | ||||||
|     // Name of the IXMLRoot |     // Name of the IXMLRoot | ||||||
|     public abstract string Type { get; } |     public abstract string Type { get; } | ||||||
|  |  | ||||||
|     // Tag Name of the Container |     // Name of the file prefix | ||||||
|     public abstract string Container { get; } |     public abstract string Prefix { get; } | ||||||
|  |      | ||||||
|  |     // XPaths to determine if container is present | ||||||
|  |     public abstract string[] XPathContainer { get; } | ||||||
|  |  | ||||||
|     // Tag Name of child objects to be collected  |     // Tag Name of child objects to be collected  | ||||||
|     public abstract Predicate<XElement> IsCollectedObject { get; } |     public abstract Predicate<XElement> IsCollectedObject { get; } | ||||||
| @@ -14,20 +18,27 @@ public interface IXMLRoot { | |||||||
|     // Gets the Key of a collected object |     // Gets the Key of a collected object | ||||||
|     public abstract Func<XElement, string?> GetKey { get; } |     public abstract Func<XElement, string?> GetKey { get; } | ||||||
|  |  | ||||||
|     // Is the pesented XElement such a root?  |     // Can the Root be found within that document?  | ||||||
|     public bool IsTypeOf(XElement xelement) { |     public List<XElement>? IsTypeOf(XElement root) { | ||||||
|         if (xelement.Name == this.Container) return true; |         List<XElement>? ret = null; | ||||||
|         return false; |         foreach (var p in XPathContainer) { | ||||||
|  |             var elements = root.XPathSelectElements(p); | ||||||
|  |             if (elements != null && elements.Any()) { | ||||||
|  |                 if (ret == null) ret = new List<XElement>(); | ||||||
|  |                 ret.AddRange(elements); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Generate certain metadat fields to display about this root |     // Generate certain metadat fields to display about this root | ||||||
|     public abstract List<(string, string)>? GenerateFields(XMLRootDocument document); |     public abstract List<(string, string?)>? GenerateFields(XMLRootDocument document); | ||||||
|  |  | ||||||
|     // Generate an identification string of which the hash will be the filename.  |     // Generate an identification string of which the hash will be the filename.  | ||||||
|     // The second string will be appended literally for convenience. |     // The second string will be appended literally for convenience. | ||||||
|     // If the queries of two document are equal they replace each other |     // If the queries of two document are equal they replace each other | ||||||
|     // If the queries and the date of two documents are equal the later one gets deleted |     // If the queries and the date of two documents are equal the later one gets deleted | ||||||
|     public abstract (string?, string) GenerateIdentificationString(XElement element); |     public abstract (string?, string?) GenerateIdentificationString(XElement element); | ||||||
|  |  | ||||||
|     // Further deciding which of two documents replaces which |     // Further deciding which of two documents replaces which | ||||||
|     public abstract bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2); |     public abstract bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2); | ||||||
| @@ -44,4 +55,6 @@ public interface IXMLRoot { | |||||||
|         }); |         }); | ||||||
|         return ret; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public abstract XElement CreateHamannDocument(XElement element); | ||||||
| } | } | ||||||
| @@ -3,6 +3,7 @@ using System.Xml.Linq; | |||||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
|  |  | ||||||
| public interface IXMLService { | public interface IXMLService { | ||||||
|  |     public IXMLRoot? GetRoot(string name); | ||||||
|     public List<IXMLRoot>? GetRoots(); |     public List<IXMLRoot>? GetRoots(); | ||||||
|     public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState); |     public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState); | ||||||
| } | } | ||||||
| @@ -1,28 +1,63 @@ | |||||||
| namespace HaWeb.XMLParser; | namespace HaWeb.XMLParser; | ||||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  | using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
|  |  | ||||||
| public class XMLRootDocument { | public class XMLRootDocument { | ||||||
|     public string Type {get; private set; } |     private XElement? _Element; | ||||||
|     public DateTime Date { get; private set; } |     private string? _filename; | ||||||
|     public XElement Root { get; private set; } |     private string? _path; | ||||||
|     public (string?, string) IdentificationString { get; private set; } |     private IXMLService _xmlService; | ||||||
|  |  | ||||||
|     public Dictionary<string, XElement>? Elements { get; set; } |     [JsonIgnore] | ||||||
|  |     public XElement Root {  | ||||||
|  |         get { | ||||||
|  |             if (_Element == null) { | ||||||
|  |                 _Element = GetElement(); | ||||||
|  |             } | ||||||
|  |             return _Element; | ||||||
|  |     } } | ||||||
|  |  | ||||||
|  |     public string FileName { get { | ||||||
|  |         if (_filename == null)  | ||||||
|  |             _filename = _CreateFilename(); | ||||||
|  |         return _filename; | ||||||
|  |     } } | ||||||
|  |  | ||||||
|  |     public string Prefix { get; private set; } | ||||||
|  |     public DateTime Date { get; private set; } | ||||||
|  |      | ||||||
|  |     public (string?, string?) IdentificationString { get; private set; } | ||||||
|  |     [JsonIgnore] | ||||||
|     public List<(string, string)>? Fields { get; set; } |     public List<(string, string)>? Fields { get; set; } | ||||||
|  |  | ||||||
|     public XMLRootDocument(string type, (string?, string) idString, XElement root) { |     // Entry point for file reading | ||||||
|         Type = type; |     public XMLRootDocument(IXMLService xmlService, string prefix, (string?, string?) idString, DateTime date, string path) { | ||||||
|  |         _xmlService = xmlService; | ||||||
|  |         _path = path; | ||||||
|  |         Prefix = prefix; | ||||||
|         IdentificationString = idString; |         IdentificationString = idString; | ||||||
|         Date = DateTime.Today; |         Date = date; | ||||||
|         Root = root; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public string CreateFilename() { |     // Entry point for XML upload reading | ||||||
|         var filename = _removeInvalidChars(Type) + "_"; |     public XMLRootDocument(IXMLService xmlService, string prefix, (string?, string?) idString, XElement element) { | ||||||
|         if (IdentificationString.Item1 != null) filename += _removeInvalidChars(IdentificationString.Item1) + "_";  |         _xmlService = xmlService; | ||||||
|         filename += _removeInvalidChars(IdentificationString.Item2) + "_"; |         Prefix = prefix; | ||||||
|  |         IdentificationString = idString; | ||||||
|  |         Date = DateTime.Today; | ||||||
|  |         _Element = element; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private string _CreateFilename() { | ||||||
|  |         var filename = _removeInvalidChars(Prefix) + "_"; | ||||||
|  |         if (!String.IsNullOrWhiteSpace(IdentificationString.Item1)) { | ||||||
|  |             var hash = IdentificationString.Item1.GetHashCode().ToString("X8"); | ||||||
|  |             filename += hash + "_"; | ||||||
|  |         } | ||||||
|  |         if (!String.IsNullOrWhiteSpace(IdentificationString.Item2)) filename += _removeInvalidChars(IdentificationString.Item2) + "_"; | ||||||
|         filename += _removeInvalidChars(Date.Year.ToString() + "-" + Date.Month.ToString() + "-" + Date.Day.ToString()); |         filename += _removeInvalidChars(Date.Year.ToString() + "-" + Date.Month.ToString() + "-" + Date.Day.ToString()); | ||||||
|         return filename; |         return filename + ".xml"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private string _removeInvalidChars(string? s) { |     private string _removeInvalidChars(string? s) { | ||||||
| @@ -30,12 +65,42 @@ public class XMLRootDocument { | |||||||
|         foreach (var c in Path.GetInvalidFileNameChars()) { |         foreach (var c in Path.GetInvalidFileNameChars()) { | ||||||
|             s = s.Replace(c, '-'); |             s = s.Replace(c, '-'); | ||||||
|         } |         } | ||||||
|  |         s = s.Replace('_', '-'); | ||||||
|         return s; |         return s; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public async void Save(Stream stream) { |     private XElement GetElement() { | ||||||
|         var nr = new XElement("opus"); |         if (_path == null || String.IsNullOrWhiteSpace(_path)) | ||||||
|         nr.AddFirst(Root); |             throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden."); | ||||||
|         await nr.SaveAsync(stream, SaveOptions.DisableFormatting, new CancellationToken()); |          | ||||||
|  |         var root = _xmlService.GetRoot(Prefix); | ||||||
|  |         if (root == null) | ||||||
|  |             throw new Exception("Kein gültiges Hamann-Dokument: " + _path + "Vom Prefix: " + Prefix); | ||||||
|  |          | ||||||
|  |         XDocument? doc = null; | ||||||
|  |         try { | ||||||
|  |             doc = XDocument.Load(_path, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo); | ||||||
|  |         }  | ||||||
|  |         catch (Exception ex) { | ||||||
|  |             throw new Exception("Fehler beim Lesen des Dokuments: " + ex.Message); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (doc == null || doc.Root == null) | ||||||
|  |             throw new Exception("Das Dokument ist ungültig und kann nicht gelesen werden: " + _path); | ||||||
|  |  | ||||||
|  |         var element = root.IsTypeOf(doc.Root); | ||||||
|  |         if (element == null || !element.Any()) | ||||||
|  |             throw new Exception("Kein gültiges Hamann-Dokument: " + _path + "Vom Prefix: " + Prefix); | ||||||
|  |  | ||||||
|  |         return element.First(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task Save(Stream stream, ModelStateDictionary state) { | ||||||
|  |         var root = _xmlService.GetRoot(Prefix); | ||||||
|  |         if (root == null) { | ||||||
|  |             state.AddModelError("Error", "No corresponding Root Element found."); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         await root.CreateHamannDocument(Root).SaveAsync(stream, SaveOptions.DisableFormatting, new CancellationToken()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -11,10 +11,15 @@ public class XMLService : IXMLService { | |||||||
|         types.ForEach( x => { |         types.ForEach( x => { | ||||||
|             if (this._Roots == null) this._Roots = new Dictionary<string, IXMLRoot>(); |             if (this._Roots == null) this._Roots = new Dictionary<string, IXMLRoot>(); | ||||||
|             var instance = (IXMLRoot)Activator.CreateInstance(x)!; |             var instance = (IXMLRoot)Activator.CreateInstance(x)!; | ||||||
|             if (instance != null) this._Roots.Add(instance.Type, instance); |             if (instance != null) this._Roots.Add(instance.Prefix, instance); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public IXMLRoot? GetRoot(string name) { | ||||||
|  |         _Roots.TryGetValue(name, out var root); | ||||||
|  |         return root; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public List<IXMLRoot>? GetRoots() => this._Roots == null ? null : this._Roots.Values.ToList(); |     public List<IXMLRoot>? GetRoots() => this._Roots == null ? null : this._Roots.Values.ToList(); | ||||||
|  |  | ||||||
|     public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) { |     public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) { | ||||||
| @@ -23,41 +28,23 @@ public class XMLService : IXMLService { | |||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         var res = _testElements(document.Root.Elements()); |  | ||||||
|         if (document.Root.Element("data") != null) { |  | ||||||
|             var datares = _testElements(document.Element("data")!.Elements()); |  | ||||||
|             if (datares != null && res == null) res = datares; |  | ||||||
|             else if (datares != null) res!.AddRange(datares); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return res; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private List<XMLRootDocument>? _testElements(IEnumerable<XElement>? elements) { |  | ||||||
|         if (elements == null) return null; |  | ||||||
|         List<XMLRootDocument>? res = null; |         List<XMLRootDocument>? res = null; | ||||||
|         foreach (var elem in elements) { |         if (document.Root != null && _Roots != null) { | ||||||
|            var doc = _testElement(elem); |  | ||||||
|            if (doc != null) { |  | ||||||
|                if (res == null) res = new List<XMLRootDocument>(); |  | ||||||
|                res.Add(doc); |  | ||||||
|            } |  | ||||||
|         } |  | ||||||
|         return res; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private XMLRootDocument? _testElement(XElement? element) { |  | ||||||
|         if (element == null || _Roots == null) return null; |  | ||||||
|             foreach (var (_, root) in _Roots) { |             foreach (var (_, root) in _Roots) { | ||||||
|             if(root.IsTypeOf(element)) |                 var elements = root.IsTypeOf(document.Root); | ||||||
|                 return _createXMLRootDocument(root, element); |                 if (elements != null &&  elements.Any()) | ||||||
|  |                     foreach (var elem in elements) { | ||||||
|  |                         if (res == null) res = new List<XMLRootDocument>(); | ||||||
|  |                         res.Add(_createXMLRootDocument(root, elem)); | ||||||
|                     } |                     } | ||||||
|         return null; |             } | ||||||
|  |         } | ||||||
|  |         if (res == null) ModelState.AddModelError("Error", "Kein zum Hamann-Briefe-Projekt passendes XML gefunden."); | ||||||
|  |         return res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) { |     private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) { | ||||||
|         var doc = new XMLRootDocument(Root.Type, Root.GenerateIdentificationString(element), element); |         var doc = new XMLRootDocument(this, Root.Prefix, Root.GenerateIdentificationString(element), element); | ||||||
|         doc.Elements = Root.GetCollectedObjects(doc); |  | ||||||
|         doc.Fields = Root.GenerateFields(doc); |         doc.Fields = Root.GenerateFields(doc); | ||||||
|         return doc; |         return doc; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|     "UpdateService": false |     "UpdateService": false | ||||||
|   }, |   }, | ||||||
|   "AllowedHosts": "*", |   "AllowedHosts": "*", | ||||||
|   "StoredFilesPathLinux": "/home/simon/Downloads/", |   "StoredFilePathLinux": "/home/simon/Downloads/test/", | ||||||
|   "StoredFilePathWindows": "D:/test/", |   "StoredFilePathWindows": "D:/test/", | ||||||
|   "FileSizeLimit": 52428800 |   "FileSizeLimit": 52428800 | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								XML/XML/test_empty.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								XML/XML/test_empty.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <opus><definitions></definitions></opus> | ||||||
		Reference in New Issue
	
	Block a user
	 schnulller
					schnulller