diff --git a/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
index 7b24482..93d28b2 100644
--- a/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
+++ b/XSDVisualiser.Desktop/ViewModels/MainWindowViewModel.cs
@@ -4,6 +4,10 @@ using XSDVisualiser.Core;
namespace XSDVisualiser.Desktop.ViewModels;
+///
+/// View model exposing the parsed schema for binding in the main window.
+/// Provides selection state and information about the currently loaded XSD file.
+///
public class MainWindowViewModel(SchemaModel model) : INotifyPropertyChanged
{
private string? _currentFilePath;
@@ -11,6 +15,10 @@ public class MainWindowViewModel(SchemaModel model) : INotifyPropertyChanged
private SchemaNode? _selectedNode;
private SchemaNode? _selectedRootElement;
+ ///
+ /// Parsed schema model currently displayed by the UI.
+ /// Setting this property updates dependent properties and notifies bindings.
+ ///
public SchemaModel Model
{
get => _model;
@@ -24,8 +32,14 @@ public class MainWindowViewModel(SchemaModel model) : INotifyPropertyChanged
}
}
+ ///
+ /// All global elements defined in the loaded schema.
+ ///
public IEnumerable RootElements => _model?.RootElements ?? Enumerable.Empty();
+ ///
+ /// If set, filters the view to show only this root element and its subtree.
+ ///
public SchemaNode? SelectedRootElement
{
get => _selectedRootElement;
diff --git a/XSDVisualiser.Desktop/Views/LeftTreeView.axaml.cs b/XSDVisualiser.Desktop/Views/LeftTreeView.axaml.cs
index b24ee8b..58f71cd 100644
--- a/XSDVisualiser.Desktop/Views/LeftTreeView.axaml.cs
+++ b/XSDVisualiser.Desktop/Views/LeftTreeView.axaml.cs
@@ -15,6 +15,10 @@ using XSDVisualiser.Desktop.ViewModels;
namespace XSDVisualiser.Desktop.Views;
+///
+/// Left-side tree view control that displays parsed XSD schema nodes and provides actions
+/// such as copy-as-TSV, validate against XML, and export sample XML.
+///
public partial class LeftTreeView : UserControl
{
public LeftTreeView()
@@ -24,7 +28,6 @@ public partial class LeftTreeView : UserControl
private async void OnCopyAsTsvClick(object? sender, RoutedEventArgs e)
{
- // Determine the node from the menu item's DataContext
var node = (sender as MenuItem)?.DataContext as SchemaNode;
if (node == null)
node =
@@ -40,7 +43,6 @@ public partial class LeftTreeView : UserControl
private async void OnValidateAgainstXmlClick(object? sender, RoutedEventArgs e)
{
- // Resolve node from context
var node = (sender as MenuItem)?.DataContext as SchemaNode;
if (node == null)
node = (sender as Control)?.GetVisualAncestors().OfType().FirstOrDefault()?.DataContext as SchemaNode;
@@ -96,7 +98,6 @@ public partial class LeftTreeView : UserControl
private static string BuildTsv(SchemaNode root)
{
var sb = new StringBuilder();
- // Header
sb.AppendLine(
"Depth\tPath\tName\tNamespace\tTypeName\tBuiltInType\tMinOccurs\tMaxOccurs\tContentModel\tConstraints\tIsNillable");
var initialPath = root.Name ?? string.Empty;
@@ -146,7 +147,6 @@ public partial class LeftTreeView : UserControl
private static async Task TryGetLocalPathAsync(IStorageFile file)
{
- // Avalonia provides TryGetLocalPath extension for local files; otherwise, we can't access it via System.IO API.
return file.TryGetLocalPath();
}
@@ -183,10 +183,8 @@ public partial class LeftTreeView : UserControl
}
};
- // Compose content
if (dialog.Content is Grid grid)
{
- // Use a read-only TextBox so users can select text easily
var textBox = new TextBox
{
Text = text,
@@ -198,7 +196,6 @@ public partial class LeftTreeView : UserControl
var scroller = new ScrollViewer { Content = textBox };
- // Copy button
var copyButton = new Button
{
Content = "Copy",
@@ -212,7 +209,6 @@ public partial class LeftTreeView : UserControl
if (topLevel?.Clipboard != null)
{
await topLevel.Clipboard.SetTextAsync(text);
- // Provide lightweight feedback by changing content briefly
if (copyButton.Content is string)
copyButton.Content = "Copied";
await Task.Delay(1000);
diff --git a/XSDVisualiser/Models/AttributeInfo.cs b/XSDVisualiser/Models/AttributeInfo.cs
index e377aae..991bc12 100644
--- a/XSDVisualiser/Models/AttributeInfo.cs
+++ b/XSDVisualiser/Models/AttributeInfo.cs
@@ -7,15 +7,33 @@ namespace XSDVisualiser.Core;
///
public class AttributeInfo
{
+ ///
+ /// Local name of the attribute.
+ ///
[XmlAttribute] public string? Name { get; set; }
+ ///
+ /// Namespace URI of the attribute, if any.
+ ///
[XmlAttribute] public string? Namespace { get; set; }
- [XmlAttribute] public string? Use { get; set; } // optional | required | prohibited
+ ///
+ /// Usage of the attribute: optional | required | prohibited.
+ ///
+ [XmlAttribute] public string? Use { get; set; }
+ ///
+ /// The qualified type name if the attribute has a named type.
+ ///
[XmlAttribute] public string? TypeName { get; set; }
+ ///
+ /// Built-in XML Schema type code name when applicable.
+ ///
[XmlAttribute] public string? BuiltInType { get; set; }
+ ///
+ /// Optional constraints applied to the attribute's simple type.
+ ///
[XmlElement] public ConstraintSet? Constraints { get; set; }
}
\ No newline at end of file
diff --git a/XSDVisualiser/Models/ConstraintSet.cs b/XSDVisualiser/Models/ConstraintSet.cs
index 2701cd9..04f8a8c 100644
--- a/XSDVisualiser/Models/ConstraintSet.cs
+++ b/XSDVisualiser/Models/ConstraintSet.cs
@@ -7,9 +7,14 @@ namespace XSDVisualiser.Core;
///
public class ConstraintSet
{
+ ///
+ /// The qualified name of the base type this constraint set applies to, if any.
+ ///
[XmlAttribute] public string? BaseTypeName { get; set; }
- // Generic catch-all list of constraints for dynamic display and tooling
+ ///
+ /// A catch-all list of constraint entries for dynamic display and tooling.
+ ///
[XmlArray("Constraints")]
[XmlArrayItem("Constraint")]
public List Constraints { get; set; } = new();
diff --git a/XSDVisualiser/Models/SchemaNode.cs b/XSDVisualiser/Models/SchemaNode.cs
index 6766a7e..72cb53d 100644
--- a/XSDVisualiser/Models/SchemaNode.cs
+++ b/XSDVisualiser/Models/SchemaNode.cs
@@ -29,7 +29,10 @@ public class SchemaNode
[XmlArrayItem("Element")]
public List Children { get; set; } = new();
- [XmlAttribute] public string? ContentModel { get; set; } // sequence | choice | all | simple
+ ///
+ /// Content model for this node: sequence | choice | all | simple. For synthetic group nodes, may be "group".
+ ///
+ [XmlAttribute] public string? ContentModel { get; set; }
///
/// Human-readable documentation extracted from xsd:annotation/xsd:documentation.
@@ -38,14 +41,13 @@ public class SchemaNode
[XmlElement]
public string? Documentation { get; set; }
+ ///
+ /// Returns a human-readable name for UI elements (prefers Name, then TypeName).
+ ///
public override string ToString()
{
- // Used by AutoCompleteBox to get text for filtering and matching
- // Prefer Name, then TypeName, and fall back to base implementation
- if (!string.IsNullOrEmpty(Name))
- return Name!;
- if (!string.IsNullOrEmpty(TypeName))
- return TypeName!;
+ if (!string.IsNullOrEmpty(Name)) return Name!;
+ if (!string.IsNullOrEmpty(TypeName)) return TypeName!;
return base.ToString();
}
}
\ No newline at end of file
diff --git a/XSDVisualiser/Parsing/XsdSchemaParser.cs b/XSDVisualiser/Parsing/XsdSchemaParser.cs
index 1e8ab54..2e46746 100644
--- a/XSDVisualiser/Parsing/XsdSchemaParser.cs
+++ b/XSDVisualiser/Parsing/XsdSchemaParser.cs
@@ -4,10 +4,18 @@ using System.Xml.Schema;
namespace XSDVisualiser.Core;
+///
+/// Parses XML Schema (XSD) into a simplified model for visualization and tooling.
+///
public class XsdSchemaParser
{
private readonly XmlSchemaSet _set = new();
+ ///
+ /// Reads and compiles the provided XSD file into a schema set, then produces a simplified schema model.
+ ///
+ /// Path to the XSD file.
+ /// A populated representing global elements and their structures.
public SchemaModel Parse(string xsdPath)
{
_set.XmlResolver = new XmlUrlResolver();
@@ -34,8 +42,7 @@ public class XsdSchemaParser
private void ValidationCallback(object? sender, ValidationEventArgs e)
{
- // For now, we do not throw; we capture compiled info best-effort.
- // Console.Error.WriteLine($"[XSD Validation {e.Severity}] {e.Message}");
+ // Intentionally no-op: schema is parsed best-effort without throwing on compile warnings/errors.
}
private SchemaNode BuildNodeForElement(XmlSchemaElement element, string? parentContentModel)
diff --git a/XSDVisualiser/Utils/XmlValidation.cs b/XSDVisualiser/Utils/XmlValidation.cs
index 84aa382..ea166a6 100644
--- a/XSDVisualiser/Utils/XmlValidation.cs
+++ b/XSDVisualiser/Utils/XmlValidation.cs
@@ -11,12 +11,29 @@ namespace XSDVisualiser.Core;
///
public static class XmlValidator
{
+ ///
+ /// Validates an XML document against the global element specified by name and optional namespace
+ /// from the XSD located at .
+ ///
+ /// Path to the XSD file containing the target element/type definitions.
+ /// The local name of the global element to validate against.
+ /// The namespace URI of the element; may be null to auto-detect.
+ /// Path to the XML file to validate.
+ /// Aggregated validation result with errors/warnings and diagnostics.
public static XmlValidationResult ValidateAgainstElement(string xsdPath, string elementName, string? elementNamespace, string xmlPath)
{
var set = BuildSchemaSet(xsdPath);
return ValidateAgainstElement(set, elementName, elementNamespace, xmlPath);
}
+ ///
+ /// Validates an XML document against a specific global element within an already built .
+ ///
+ /// Compiled schema set to use for validation.
+ /// The local name of the global element to validate against.
+ /// The namespace URI of the element; may be null to auto-detect.
+ /// Path to the XML file to validate.
+ /// Aggregated validation result with errors/warnings and diagnostics.
public static XmlValidationResult ValidateAgainstElement(XmlSchemaSet schemas, string elementName, string? elementNamespace, string xmlPath)
{
var result = new XmlValidationResult();
@@ -428,15 +445,31 @@ public static class XmlValidator
}
}
+///
+/// Aggregates XML validation outcomes, including errors, warnings, and overall validity.
+///
public sealed class XmlValidationResult
{
private readonly List _issues = new();
+ ///
+ /// True if no validation errors have been recorded.
+ ///
public bool IsValid => _issues.TrueForAll(i => i.Severity != XmlSeverityType.Error);
+ ///
+ /// All recorded validation issues (errors and warnings) in chronological order.
+ ///
public IReadOnlyList Issues => _issues;
+ ///
+ /// All recorded validation errors.
+ ///
public IEnumerable Errors => _issues.Where(i => i.Severity == XmlSeverityType.Error);
+
+ ///
+ /// All recorded validation warnings.
+ ///
public IEnumerable Warnings => _issues.Where(i => i.Severity == XmlSeverityType.Warning);
internal void AddError(string message, int? line = null, int? position = null) =>
@@ -446,6 +479,13 @@ public sealed class XmlValidationResult
_issues.Add(new XmlValidationIssue(XmlSeverityType.Warning, message, line ?? 0, position ?? 0));
}
+///
+/// Represents a single validation issue (error or warning) with optional location information.
+///
+/// Issue severity (Error or Warning).
+/// Human-readable description of the issue.
+/// Line number in the XML where the issue occurred, if available.
+/// Column position in the XML where the issue occurred, if available.
public sealed record XmlValidationIssue(XmlSeverityType Severity, string Message, int LineNumber, int LinePosition);