Results of SyntaxCheck -> extra State

This commit is contained in:
Simon Martens
2023-09-10 16:34:49 +02:00
parent 8fd0050cf3
commit 80e593ce7c
16 changed files with 122 additions and 102 deletions

View File

@@ -13,12 +13,10 @@ public class XMLStateController : Controller {
private IHaDocumentWrappper _lib; private IHaDocumentWrappper _lib;
private readonly IXMLInteractionService _xmlService; private readonly IXMLInteractionService _xmlService;
private readonly IXMLFileProvider _xmlProvider; private readonly IXMLFileProvider _xmlProvider;
private readonly IMonitorLoop _loop; public XMLStateController(IHaDocumentWrappper lib, IXMLInteractionService xmlService, IXMLFileProvider xmlProvider) {
public XMLStateController(IMonitorLoop loop, IHaDocumentWrappper lib, IXMLInteractionService xmlService, IXMLFileProvider xmlProvider) {
_lib = lib; _lib = lib;
_xmlService = xmlService; _xmlService = xmlService;
_xmlProvider = xmlProvider; _xmlProvider = xmlProvider;
_loop = loop;
} }
[HttpGet] [HttpGet]
@@ -26,7 +24,6 @@ public class XMLStateController : Controller {
[FeatureGate(Features.AdminService)] [FeatureGate(Features.AdminService)]
[GenerateAntiforgeryTokenCookie] [GenerateAntiforgeryTokenCookie]
public IActionResult Index() { public IActionResult Index() {
_loop.StartMonitorLoop();
var library = _lib.GetLibrary(); var library = _lib.GetLibrary();
var roots = _xmlService.GetRootsList(); var roots = _xmlService.GetRootsList();
if (roots == null) return error404(); if (roots == null) return error404();
@@ -39,6 +36,7 @@ public class XMLStateController : Controller {
var model = new XMLStateViewModel("Dateiübersicht", gD, roots, hF, mF, vS) { var model = new XMLStateViewModel("Dateiübersicht", gD, roots, hF, mF, vS) {
ActiveFile = activeF, ActiveFile = activeF,
SyntaxCheck = _xmlService.Test()
}; };
return View("~/Views/Admin/Dynamic/XMLState.cshtml", model); return View("~/Views/Admin/Dynamic/XMLState.cshtml", model);
} }

View File

@@ -4,10 +4,12 @@ namespace HaWeb.FileHelpers;
public class ConfigurationMonitor { public class ConfigurationMonitor {
private System.Timers.Timer? _timer; private System.Timers.Timer? _timer;
private string[] _paths;
private (string, byte[])[]? _h; private (string, byte[])[]? _h;
private IServiceProvider _serviceProvider; private IServiceProvider _serviceProvider;
public ConfigurationMonitor(string[] paths, IServiceProvider services) { public ConfigurationMonitor(string[] paths, IServiceProvider services) {
_paths = paths;
_h = _getHash(paths); _h = _getHash(paths);
_serviceProvider = services; _serviceProvider = services;
} }
@@ -33,27 +35,25 @@ public class ConfigurationMonitor {
return true; return true;
} }
public void InvokeChanged(string[] paths) { public void InvokeChanged(IHostEnvironment _) {
var h = _getHash(paths); var h = _getHash(_paths);
if (_timer == null && !isEqual(h, _h)) { if (_timer == null && !isEqual(h, _h)) {
_h = h; _h = h;
_timer = new(5000) { AutoReset = false }; _timer = new(8000) { AutoReset = false };
_timer.Enabled = true; _timer.Enabled = true;
_timer.Elapsed += Action; _timer.Elapsed += OnChanged;
} }
} }
private void Action(Object source, System.Timers.ElapsedEventArgs e) { private void OnChanged(Object source, System.Timers.ElapsedEventArgs e) {
Console.WriteLine("Configuration changed (ConfigurationMonitor Class)"); Console.WriteLine("Configuration changed (ConfigurationMonitor Class)");
using IServiceScope serviceScope = _serviceProvider.CreateScope(); using IServiceScope serviceScope = _serviceProvider.CreateScope();
IServiceProvider provider = serviceScope.ServiceProvider; IServiceProvider provider = serviceScope.ServiceProvider;
var cP = provider.GetRequiredService<IConfiguration>(); var cP = provider.GetRequiredService<IConfiguration>();
var hP = provider.GetRequiredService<IHaDocumentWrappper>(); var hP = provider.GetRequiredService<IHaDocumentWrappper>();
hP.ParseConfiguration(cP); hP.ParseConfiguration(cP);
var fP = provider.GetRequiredService<IXMLFileProvider>(); var fP = provider.GetRequiredService<IXMLFileProvider>();
fP.Reload(cP); fP.ParseConfiguration(cP);
// _lifetime.StopApplication(); // _lifetime.StopApplication();
_timer = null; _timer = null;
} }

View File

@@ -10,7 +10,7 @@ public interface IXMLFileProvider {
public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState); public IFileInfo? SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState);
public List<IFileInfo>? GetHamannFiles(); public List<IFileInfo>? GetHamannFiles();
public (DateTime PullTime, string Hash)? GetGitData(); public (DateTime PullTime, string Hash)? GetGitData();
public void Reload(IConfiguration config); public void ParseConfiguration(IConfiguration config);
public bool HasChanged(); public bool HasChanged();
public void DeleteHamannFile(string filename); public void DeleteHamannFile(string filename);
public void Scan(); public void Scan();

View File

@@ -49,19 +49,19 @@ public class XMLFileProvider : IXMLFileProvider {
} }
_HamannFiles = _ScanHamannFiles(); _HamannFiles = _ScanHamannFiles();
// Check if hamann file already is current working tree status // Check if hamann file already is current working tree status
// -> YES: Load up the file via _lib.SetLibrary(); // -> YES: Load up the file via _lib.SetLibrary();
if (_IsAlreadyParsed()) { if (_IsAlreadyParsed()) {
_Lib.SetLibrary(_HamannFiles.First(), null, null); _Lib.SetLibrary(_HamannFiles!.First(), null, null);
if (_Lib.GetLibrary() != null) return; if (_Lib.GetLibrary() != null) return;
} }
// -> NO: Try to create a new file // -> NO: Try to create a new file
var created = xmlservice.TryCreate(); var created = _XMLService.TryCreate();
if (created != null) { if (created != null) {
var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null); var file = SaveHamannFile(created, _hamannFileProvider.GetFileInfo("./").PhysicalPath, null);
if (file != null) { if (file != null) {
_lib.SetLibrary(file, created.Document, null); _Lib.SetLibrary(file, created.Document, null);
if (_Lib.GetLibrary() != null) return; if (_Lib.GetLibrary() != null) return;
} }
} }
@@ -75,36 +75,32 @@ public class XMLFileProvider : IXMLFileProvider {
// -> There is none? Use Fallback: // -> There is none? Use Fallback:
else { else {
var options = new HaWeb.Settings.HaDocumentOptions(); var options = new HaWeb.Settings.HaDocumentOptions();
if (_lib.SetLibrary(null, null, null) == null) { if (_Lib.SetLibrary(null, null, null) == null) {
throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden."); throw new Exception("Die Fallback Hamann.xml unter " + options.HamannXMLFilePath + " kann nicht geparst werden.");
} }
} }
} }
public void Reload(IConfiguration config) { public void ParseConfiguration(IConfiguration config) {
_Branch = config.GetValue<string>("RepositoryBranch"); _Branch = config.GetValue<string>("RepositoryBranch");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
_hamannFileProvider = new PhysicalFileProvider(config.GetValue<string>("HamannFileStoreWindows"));
_bareRepositoryFileProvider = new PhysicalFileProvider(config.GetValue<string>("BareRepositoryPathWindows"));
_workingTreeFileProvider = new PhysicalFileProvider(config.GetValue<string>("WorkingTreePathWindows"));
}
else {
_hamannFileProvider = new PhysicalFileProvider(config.GetValue<string>("HamannFileStoreLinux"));
_bareRepositoryFileProvider = new PhysicalFileProvider(config.GetValue<string>("BareRepositoryPathLinux"));
_workingTreeFileProvider = new PhysicalFileProvider(config.GetValue<string>("WorkingTreePathLinux"));
}
// Create File Lists; Here and in xmlservice, which does preliminary checking
Scan(); Scan();
// Reset XMLInteractionService
if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) { if (_WorkingTreeFiles != null && _WorkingTreeFiles.Any()) {
_XMLService.Collect(_WorkingTreeFiles); _XMLService.Collect(_WorkingTreeFiles);
} }
_HamannFiles = _ScanHamannFiles(); _HamannFiles = _ScanHamannFiles();
if (_HamannFiles != null && _HamannFiles.Select(x => x.Name).Contains(_Lib.GetActiveFile().Name)) {
_Lib.SetLibrary(_Lib.GetActiveFile(), null, null);
if (_Lib.GetLibrary() != null) return;
}
// Failed to reload File, reload it all, same procedure as above:
// Check if hamann file already is current working tree status // Check if hamann file already is current working tree status
// -> YES: Load up the file via _lib.SetLibrary(); // -> YES: Load up the file via _lib.SetLibrary();
if (_IsAlreadyParsed()) { if (_IsAlreadyParsed()) {
_Lib.SetLibrary(_HamannFiles.First(), null, null); _Lib.SetLibrary(_HamannFiles!.First(), null, null);
if (_Lib.GetLibrary() != null) return; if (_Lib.GetLibrary() != null) return;
} }

View File

@@ -27,13 +27,4 @@ public class FileList {
public List<XMLRootDocument>? GetFileList() public List<XMLRootDocument>? GetFileList()
=> this._Files != null ? this._Files.ToList() : null; => this._Files != null ? this._Files.ToList() : null;
public FileList Clone() {
var ret = new FileList(this.XMLRoot);
if (_Files != null)
foreach (var file in _Files) {
ret.Add(file);
}
return ret;
}
} }

View File

@@ -1,6 +0,0 @@
namespace HaWeb.Models;
using System.ComponentModel.DataAnnotations;
public class YearSetting {
[Required]
public int EndYear { get; set; }
}

View File

@@ -1,22 +1,22 @@
namespace HaWeb.Models; namespace HaWeb.Models;
public class SyntaxCheckModel { public class SyntaxCheckModel {
public string Prefix { get; private set; } public string File { get; private set; }
public List<SyntaxError>? Errors { get; set; } public List<SyntaxError>? Errors { get; private set; }
public List<SyntaxError>? Warnings { get; set; }
public SyntaxCheckModel(string prefix) { public SyntaxCheckModel(string file) {
Prefix = prefix; File = file;
}
public void Log(int? line, int? column, string msg) {
if (String.IsNullOrWhiteSpace(msg)) return;
if (Errors == null) Errors = new();
// var prefix = DateTime.Now.ToLongDateString() + ": ";
Errors.Add(new SyntaxError(line, column, msg));
}
public void ResetLog() {
Errors = null;
} }
} }
public class SyntaxError {
public string Message { get; private set; }
public string? File { get; set; }
public string? Line { get; set; }
public string? Column { get; set; }
public SyntaxError(string message) {
Message = message;
}
}

View File

@@ -0,0 +1,13 @@
namespace HaWeb.Models;
public class SyntaxError {
public string Message { get; private set; }
public int? Line { get; set; }
public int? Column { get; set; }
public SyntaxError(int? line, int? column, string message) {
Line = line;
Column = column;
Message = message;
}
}

View File

@@ -19,6 +19,9 @@ public class XMLStateViewModel {
// Verfügbare (Gesamt-)Dateien // Verfügbare (Gesamt-)Dateien
public List<IFileInfo>? HamannFiles { get; set; } public List<IFileInfo>? HamannFiles { get; set; }
// Syntax-Check-Resultate
public Dictionary<string, SyntaxCheckModel>? SyntaxCheck { get; set; }
public XMLStateViewModel( public XMLStateViewModel(
string title, string title,
(DateTime PullTime, string Hash)? gitData, (DateTime PullTime, string Hash)? gitData,

View File

@@ -26,8 +26,6 @@ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
builder.Configuration.AddJsonFile(p, optional: true, reloadOnChange: true); builder.Configuration.AddJsonFile(p, optional: true, reloadOnChange: true);
} }
// Create initial Data // Create initial Data
var tS = new XMLTestService(); var tS = new XMLTestService();
var XMLIS = new XMLInteractionService(builder.Configuration, tS); var XMLIS = new XMLInteractionService(builder.Configuration, tS);
@@ -59,7 +57,7 @@ var cM = new ConfigurationMonitor(configpaths.ToArray(), app.Services);
ChangeToken.OnChange( ChangeToken.OnChange(
() => app.Configuration.GetReloadToken(), () => app.Configuration.GetReloadToken(),
(state) => cM.InvokeChanged(state), (state) => cM.InvokeChanged(state),
configpaths.ToArray() app.Environment
); );
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@@ -25,8 +25,18 @@
<td>@f.GetLastModified()</td> <td>@f.GetLastModified()</td>
@if (f.IsValid) { @if (f.IsValid) {
<td>Valid! @f.GetLog()</td> <td>Valid! @f.GetLog()</td>
<td>
@if (Model.SyntaxCheck[f.FileName] != null && Model.SyntaxCheck[f.FileName].Errors != null) {
<ul>
@foreach(var e in Model.SyntaxCheck[f.FileName]?.Errors) {
<li>@e.Line @e.Column @e.Message </li>
}
</ul>
}
</td>
} else { } else {
<td>@f.GetLog()</td> <td>@f.GetLog()</td>
<td> </td>
} }
</tr> </tr>
} }

View File

@@ -16,6 +16,7 @@ public interface IXMLInteractionService {
public List<IXMLRoot>? GetRootsList(); public List<IXMLRoot>? GetRootsList();
public void CreateSearchables(XDocument document); public void CreateSearchables(XDocument document);
public List<FileModel>? GetManagedFiles(); public List<FileModel>? GetManagedFiles();
public Dictionary<string, SyntaxCheckModel>? Test();
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader, ILibrary? lib); public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? SearchCollection(string collection, string searchword, IReaderService reader, ILibrary? lib);
public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? GetPreviews(List<(string, List<Marginal>)> places, IReaderService reader, ILibrary lib); public List<(string Index, List<(string Page, string Line, string Preview, string Identifier)> Results)>? GetPreviews(List<(string, List<Marginal>)> places, IReaderService reader, ILibrary lib);
} }

View File

@@ -86,11 +86,12 @@ public class XMLInteractionService : IXMLInteractionService {
public void Collect(List<IFileInfo> files) { public void Collect(List<IFileInfo> files) {
if (files == null || !files.Any()) return; if (files == null || !files.Any()) return;
_ValidState = true; _ValidState = true;
List<FileModel> res = new List<FileModel>(); Dictionary<string, FileList?>? lF = new Dictionary<string, FileList?>();
List<FileModel> fM = new List<FileModel>();
foreach (var f in files) { foreach (var f in files) {
var sb = new StringBuilder(); var sb = new StringBuilder();
var m = _CreateFileModel(f, null); var m = _CreateFileModel(f, null);
res.Add(m); fM.Add(m);
// 1. Open File for Reading // 1. Open File for Reading
try { try {
using (Stream file = f.CreateReadStream()) { using (Stream file = f.CreateReadStream()) {
@@ -118,9 +119,8 @@ public class XMLInteractionService : IXMLInteractionService {
// Success! File can be recognized and parsed. // Success! File can be recognized and parsed.
m.Validate(); m.Validate();
foreach (var d in docs) { foreach (var d in docs) {
if (_Loaded == null) _Loaded = new Dictionary<string, FileList?>(); if (!lF.ContainsKey(d.Prefix)) lF.Add(d.Prefix, new FileList(d.XMLRoot));
if (!_Loaded.ContainsKey(d.Prefix)) _Loaded.Add(d.Prefix, new FileList(d.XMLRoot)); lF[d.Prefix]!.Add(d);
_Loaded[d.Prefix]!.Add(d);
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
@@ -128,20 +128,26 @@ public class XMLInteractionService : IXMLInteractionService {
continue; continue;
} }
} }
if(res.Any()) this._ManagedFiles = res;
// Set validity // Set data
this._ManagedFiles = fM;
this._Loaded = lF;
foreach (var f in _ManagedFiles) { foreach (var f in _ManagedFiles) {
if (!f.IsValid) _ValidState = false; if (!f.IsValid) this._ValidState = false;
break; break;
} }
}
// TODO: Speed up this: public Dictionary<string, SyntaxCheckModel>? Test() {
if (_Loaded == null) return null;
// TODO: Speed up this, move it into a background task:
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
_testService.Test(this); var res = this._Loaded?.SelectMany(x => x.Value?.GetFileList()?.Select(x => x.File)).Distinct().Select(x => x.FileName);
var ret = _testService.Test(this._Loaded, res.ToDictionary(x => x, y => new SyntaxCheckModel(y)));
sw.Stop(); sw.Stop();
Console.WriteLine("Syntaxcheck " + sw.ElapsedMilliseconds.ToString() + " ms"); Console.WriteLine("Syntaxcheck " + sw.ElapsedMilliseconds.ToString() + " ms");
return ret;
} }
public XElement? TryCreate() { public XElement? TryCreate() {

View File

@@ -1,3 +1,4 @@
using HaWeb.Models;
using HaWeb.XMLParser; using HaWeb.XMLParser;
namespace HaWeb.XMLTests; namespace HaWeb.XMLTests;
@@ -7,5 +8,5 @@ public interface IXMLTestService {
public Dictionary<string, INodeRule>? Ruleset { get; } public Dictionary<string, INodeRule>? Ruleset { get; }
public Dictionary<string, ICollectionRule>? CollectionRuleset { get; } public Dictionary<string, ICollectionRule>? CollectionRuleset { get; }
public void Test(IXMLInteractionService _XMLService); public Dictionary<string, SyntaxCheckModel>? Test(Dictionary<string, FileList?>? _LoadedFiles, Dictionary<string, SyntaxCheckModel> _Results);
} }

View File

@@ -1,4 +1,6 @@
namespace HaWeb.XMLTests; namespace HaWeb.XMLTests;
using HaWeb.Models;
using HaWeb.XMLParser; using HaWeb.XMLParser;
public class XMLTestService : IXMLTestService { public class XMLTestService : IXMLTestService {
@@ -7,28 +9,26 @@ public class XMLTestService : IXMLTestService {
public XMLTestService() { public XMLTestService() {
var roottypes = _GetAllTypesThatImplementInterface<INodeRule>().ToList(); var roottypes = _GetAllTypesThatImplementInterface<INodeRule>().ToList();
roottypes.ForEach( x => { roottypes.ForEach( x => {
if (this.Ruleset == null) this.Ruleset = new Dictionary<string, INodeRule>(); if (this.Ruleset == null) this.Ruleset = new();
var instance = (INodeRule)Activator.CreateInstance(x)!; var instance = (INodeRule)Activator.CreateInstance(x)!;
if (instance != null) this.Ruleset.Add(instance.Name, instance); if (instance != null) this.Ruleset.Add(instance.Name, instance);
}); });
var collectionruleset = _GetAllTypesThatImplementInterface<ICollectionRule>().ToList(); var collectionruleset = _GetAllTypesThatImplementInterface<ICollectionRule>().ToList();
collectionruleset.ForEach( x => { collectionruleset.ForEach( x => {
if (this.CollectionRuleset == null) this.CollectionRuleset = new Dictionary<string, ICollectionRule>(); if (this.CollectionRuleset == null) this.CollectionRuleset = new();
var instance = (ICollectionRule)Activator.CreateInstance(x)!; var instance = (ICollectionRule)Activator.CreateInstance(x)!;
if (instance != null) this.CollectionRuleset.Add(instance.Name, instance); if (instance != null) this.CollectionRuleset.Add(instance.Name, instance);
}); });
} }
public void Test(IXMLInteractionService _XMLService) { public Dictionary<string, SyntaxCheckModel>? Test(Dictionary<string, FileList?>? _Loaded, Dictionary<string, SyntaxCheckModel> _Results) {
var docs = _XMLService.GetLoaded(); if (_Loaded == null) return null;
if (docs == null) return; var tester = new XMLTester(this, _Loaded, _Results);
var tester = new XMLTester(this, docs); return tester.Test();
tester.Test();
} }
private IEnumerable<Type> _GetAllTypesThatImplementInterface<T>() private IEnumerable<Type> _GetAllTypesThatImplementInterface<T>() {
{
return System.Reflection.Assembly.GetExecutingAssembly() return System.Reflection.Assembly.GetExecutingAssembly()
.GetTypes() .GetTypes()
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface); .Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);

View File

@@ -9,12 +9,14 @@ public class XMLTester {
private Dictionary<string, INodeRule>? _Ruleset; private Dictionary<string, INodeRule>? _Ruleset;
private Dictionary<string, ICollectionRule>? _CollectionRuleset; private Dictionary<string, ICollectionRule>? _CollectionRuleset;
private List<XMLRootDocument>? _Documents; private List<XMLRootDocument>? _Documents;
private Dictionary<string, SyntaxCheckModel> _Results;
private Dictionary<string, HashSet<string>>? _IDs; private Dictionary<string, HashSet<string>>? _IDs;
private Dictionary<string, HashSet<string>>? _CollectionIDs; private Dictionary<string, HashSet<string>>? _CollectionIDs;
private Dictionary<string, List<(XElement, XMLRootDocument)>?> _XPathEvaluated; private Dictionary<string, List<(XElement, XMLRootDocument)>?> _XPathEvaluated;
public XMLTester (IXMLTestService testService, Dictionary<string, Models.FileList?>? filelists) { public XMLTester (IXMLTestService testService, Dictionary<string, Models.FileList?>? filelists, Dictionary<string, SyntaxCheckModel> results) {
_Ruleset = testService.Ruleset; _Ruleset = testService.Ruleset;
_CollectionRuleset = testService.CollectionRuleset; _CollectionRuleset = testService.CollectionRuleset;
_Results = results;
if (filelists != null) { if (filelists != null) {
foreach (var fl in filelists) { foreach (var fl in filelists) {
if (fl.Value != null) { if (fl.Value != null) {
@@ -27,20 +29,21 @@ public class XMLTester {
_XPathEvaluated = new Dictionary<string, List<(XElement, XMLRootDocument)>?>(); _XPathEvaluated = new Dictionary<string, List<(XElement, XMLRootDocument)>?>();
} }
public void Test() { public Dictionary<string, SyntaxCheckModel>? Test() {
if (_Ruleset == null) return; if (_Ruleset == null) return null;
_IDs = new Dictionary<string, HashSet<string>>(); _IDs = new Dictionary<string, HashSet<string>>();
foreach (var rule in _Ruleset) { foreach (var rule in _Ruleset) {
buildIDs(rule.Value); buildIDs(rule.Value);
checkRequiredAttributes(rule.Value); checkRequiredAttributes(rule.Value);
checkReferences(rule.Value); checkReferences(rule.Value);
} }
if (_CollectionRuleset == null) return; if (_CollectionRuleset == null) return null;
_CollectionIDs = new Dictionary<string, HashSet<string>>(); _CollectionIDs = new Dictionary<string, HashSet<string>>();
foreach (var collectionrule in _CollectionRuleset) { foreach (var collectionrule in _CollectionRuleset) {
buildIDs(collectionrule.Value); buildIDs(collectionrule.Value);
checkReferences(collectionrule.Value); checkReferences(collectionrule.Value);
} }
return _Results;
} }
private void checkReferences(INodeRule rule) { private void checkReferences(INodeRule rule) {
@@ -54,7 +57,8 @@ public class XMLTester {
if (_IDs != null && _IDs.ContainsKey(keyname) && hasattr) { if (_IDs != null && _IDs.ContainsKey(keyname) && hasattr) {
var val = e.Item1.Attribute(r.LinkAttribute)!.Value; var val = e.Item1.Attribute(r.LinkAttribute)!.Value;
if (!_IDs[keyname].Contains(val)) { if (!_IDs[keyname].Contains(val)) {
e.Item2.File.Log(generateLogMessage(e.Item1) + "Verlinktes Element " + val + " nicht gefunden."); var lc = getLineColumn(e.Item1);
_Results[e.Item2.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + val + " nicht gefunden.");
} }
} }
} }
@@ -69,7 +73,8 @@ public class XMLTester {
if (elemens != null && elemens.Any()) { if (elemens != null && elemens.Any()) {
foreach(var r in rule.GenerateBacklinkString(elemens)) { foreach(var r in rule.GenerateBacklinkString(elemens)) {
if (!r.Item4 && !_CollectionIDs[rule.Name].Contains(r.Item1)) { if (!r.Item4 && !_CollectionIDs[rule.Name].Contains(r.Item1)) {
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden."); var lc = getLineColumn(r.Item2);
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
} }
if (r.Item4) { if (r.Item4) {
var coll = _CollectionIDs[rule.Name]; var coll = _CollectionIDs[rule.Name];
@@ -77,15 +82,18 @@ public class XMLTester {
var searchterm = items[0]; var searchterm = items[0];
var found = coll.Where(x => x.StartsWith(searchterm)); var found = coll.Where(x => x.StartsWith(searchterm));
if (items[0] == "NA" || found == null || !found.Any()) { if (items[0] == "NA" || found == null || !found.Any()) {
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden."); var lc = getLineColumn(r.Item2);
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
} else { } else {
for (var i = 1; i < items.Length; i++) { for (var i = 1; i < items.Length; i++) {
if (items[i] == "NA") break; if (items[i] == "NA") break;
else { else {
searchterm = searchterm + "-" + items[i]; searchterm = searchterm + "-" + items[i];
found = found.Where(x => x.StartsWith(searchterm)); found = found.Where(x => x.StartsWith(searchterm));
if (found == null || !found.Any()) if (found == null || !found.Any()) {
r.Item3.File.Log(generateLogMessage(r.Item2) + "Verlinktes Element " + r.Item1 + " nicht gefunden."); var lc = getLineColumn(r.Item2);
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Verlinktes Element " + r.Item1 + " nicht gefunden.");
}
} }
} }
} }
@@ -126,7 +134,8 @@ public class XMLTester {
if (elemens != null && elemens.Any()) { if (elemens != null && elemens.Any()) {
foreach (var r in rule.GenerateIdentificationStrings(elemens)) { foreach (var r in rule.GenerateIdentificationStrings(elemens)) {
if (!hs.Add(r.Item1)) { if (!hs.Add(r.Item1)) {
r.Item3.File.Log(generateLogMessage(r.Item2) + "Brief-Seite-Zeile " + r.Item1 + " mehrdeutig."); var lc = getLineColumn(r.Item2);
_Results[r.Item3.File.FileName].Log(lc.Item1, lc.Item2, "Brief-Seite-Zeile " + r.Item1 + " mehrdeutig.");
} }
} }
} }
@@ -143,7 +152,8 @@ public class XMLTester {
foreach (var e in elements) { foreach (var e in elements) {
if (checkAttribute(e.Item1, attribute, e.Item2)) { if (checkAttribute(e.Item1, attribute, e.Item2)) {
if (!hs.Add(e.Item1.Attribute(attribute)!.Value)) { if (!hs.Add(e.Item1.Attribute(attribute)!.Value)) {
e.Item2.File.Log(generateLogMessage(e.Item1) + "Attributwert " + e.Item1.Attribute(attribute)!.Value + " doppelt."); var lc = getLineColumn(e.Item1);
_Results[e.Item2.File.FileName].Log(lc.Item1, lc.Item2, "Attributwert " + e.Item1.Attribute(attribute)!.Value + " doppelt.");
} }
} }
} }
@@ -152,18 +162,17 @@ public class XMLTester {
private bool checkAttribute(XElement element, string attributename, XMLRootDocument doc, bool log = true) { private bool checkAttribute(XElement element, string attributename, XMLRootDocument doc, bool log = true) {
if (!element.HasAttributes || element.Attribute(attributename) == null) { if (!element.HasAttributes || element.Attribute(attributename) == null) {
if (log) doc.File.Log(generateLogMessage(element) + "Attribut " + attributename + " fehlt."); if (log) {
var lc = getLineColumn(element);
_Results[doc.File.FileName].Log(lc.Item1, lc.Item2,"Attribut " + attributename + " fehlt.");
};
return false; return false;
} }
return true; return true;
} }
private string generateLogMessage(XElement element) { private (int, int) getLineColumn(XElement element) {
return "Zeile " + return (((IXmlLineInfo)element).LineNumber, ((IXmlLineInfo)element).LinePosition);
((IXmlLineInfo)element).LineNumber.ToString() +
", Element " +
element.Name +
": ";
} }
// Cache for XPATH evaluation // Cache for XPATH evaluation