diff --git a/XSDVisualiser.Desktop/Views/RightDetailsView.axaml b/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
index 49891e3..98faab9 100644
--- a/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
+++ b/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
@@ -39,6 +39,14 @@
+
+
+
+
+
+
+
+
diff --git a/XSDVisualiser/Models/XsdSchemaModel.cs b/XSDVisualiser/Models/XsdSchemaModel.cs
index bfd4cb7..bb1c322 100644
--- a/XSDVisualiser/Models/XsdSchemaModel.cs
+++ b/XSDVisualiser/Models/XsdSchemaModel.cs
@@ -55,6 +55,13 @@ namespace XSDVisualiser.Models
[XmlAttribute]
public string? ContentModel { get; set; } // sequence | choice | all | simple
+ ///
+ /// Human-readable documentation extracted from xsd:annotation/xsd:documentation.
+ /// Prefer element-level documentation; falls back to type-level documentation.
+ ///
+ [XmlElement]
+ public string? Documentation { get; set; }
+
public override string ToString()
{
// Used by AutoCompleteBox to get text for filtering and matching
diff --git a/XSDVisualiser/Parsing/XsdSchemaParser.cs b/XSDVisualiser/Parsing/XsdSchemaParser.cs
index 9e69023..a2c9a31 100644
--- a/XSDVisualiser/Parsing/XsdSchemaParser.cs
+++ b/XSDVisualiser/Parsing/XsdSchemaParser.cs
@@ -1,5 +1,6 @@
using System.Xml;
using System.Xml.Schema;
+using System.Text;
using XSDVisualiser.Models;
namespace XSDVisualiser.Core
@@ -54,6 +55,9 @@ namespace XSDVisualiser.Core
ContentModel = parentContentModel
};
+ // Prefer element-level documentation
+ node.Documentation = ExtractDocumentation(element);
+
var type = ResolveElementType(element);
if (type == null) return node;
node.TypeName = GetQualifiedTypeName(type);
@@ -62,6 +66,20 @@ namespace XSDVisualiser.Core
node.BuiltInType = type.Datatype.TypeCode.ToString();
}
+ // Fallback to type-level documentation if none on element
+ if (string.IsNullOrWhiteSpace(node.Documentation))
+ {
+ switch (type)
+ {
+ case XmlSchemaComplexType ctDoc:
+ node.Documentation = ExtractDocumentation(ctDoc);
+ break;
+ case XmlSchemaSimpleType stDoc:
+ node.Documentation = ExtractDocumentation(stDoc);
+ break;
+ }
+ }
+
switch (type)
{
case XmlSchemaComplexType ct:
@@ -413,5 +431,46 @@ namespace XSDVisualiser.Core
}
}
}
+ private static string? ExtractDocumentation(XmlSchemaAnnotated? annotated)
+ {
+ if (annotated?.Annotation == null) return null;
+ var sb = new StringBuilder();
+ foreach (var item in annotated.Annotation.Items)
+ {
+ if (item is not XmlSchemaDocumentation doc) continue;
+
+ if (doc.Markup is { Length: > 0 })
+ {
+ var pieceBuilder = new StringBuilder();
+ foreach (var node in doc.Markup)
+ {
+ try
+ {
+ var text = node?.InnerText;
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+ pieceBuilder.Append(text);
+ }
+ }
+ catch
+ {
+ // ignore malformed nodes
+ }
+ }
+
+ var piece = pieceBuilder.ToString().Trim();
+ if (string.IsNullOrWhiteSpace(piece)) continue;
+
+ if (sb.Length > 0) sb.AppendLine().AppendLine();
+ sb.Append(piece);
+ }
+ else if (!string.IsNullOrWhiteSpace(doc.Source))
+ {
+ // If there is a source but no markup, skip; we only render text.
+ }
+ }
+
+ return sb.Length == 0 ? null : sb.ToString();
+ }
}
}