diff --git a/XSDVisualiser.Desktop/Views/RightDetailsView.axaml b/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
index 98faab9..a2f06c1 100644
--- a/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
+++ b/XSDVisualiser.Desktop/Views/RightDetailsView.axaml
@@ -116,6 +116,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XSDVisualiser/Models/XsdSchemaModel.cs b/XSDVisualiser/Models/XsdSchemaModel.cs
index bb1c322..1ffae00 100644
--- a/XSDVisualiser/Models/XsdSchemaModel.cs
+++ b/XSDVisualiser/Models/XsdSchemaModel.cs
@@ -137,6 +137,19 @@ namespace XSDVisualiser.Models
[XmlElement]
public LengthBounds? Length { get; set; }
+
+ // Generic catch-all list of facets for dynamic display and tooling
+ [XmlArray("Facets")]
+ [XmlArrayItem("Facet")]
+ public List AllFacets { get; set; } = new();
+ }
+
+ public class FacetEntry
+ {
+ [XmlAttribute]
+ public string? Name { get; set; }
+ [XmlAttribute]
+ public string? Value { get; set; }
}
public class NumericBounds
diff --git a/XSDVisualiser/Parsing/XsdSchemaParser.cs b/XSDVisualiser/Parsing/XsdSchemaParser.cs
index a2c9a31..363aeaf 100644
--- a/XSDVisualiser/Parsing/XsdSchemaParser.cs
+++ b/XSDVisualiser/Parsing/XsdSchemaParser.cs
@@ -347,6 +347,24 @@ namespace XSDVisualiser.Core
if (source == null) return;
foreach (var e in source.Enumerations.Where(e => !target.Enumerations.Contains(e))) target.Enumerations.Add(e);
foreach (var p in source.Patterns.Where(p => !target.Patterns.Contains(p))) target.Patterns.Add(p);
+
+ // Merge generic facets
+ if (source.AllFacets != null)
+ {
+ foreach (var sf in source.AllFacets)
+ {
+ var exists = false;
+ foreach (var tf in target.AllFacets)
+ {
+ if (string.Equals(tf.Name, sf.Name, StringComparison.Ordinal) && string.Equals(tf.Value, sf.Value, StringComparison.Ordinal))
+ {
+ exists = true; break;
+ }
+ }
+ if (!exists) target.AllFacets.Add(new FacetEntry { Name = sf.Name, Value = sf.Value });
+ }
+ }
+
if (source.Numeric != null)
{
target.Numeric ??= new NumericBounds();
@@ -380,6 +398,7 @@ namespace XSDVisualiser.Core
{
foreach (var f in facets)
{
+ // Map known facets to strongly-typed buckets for backward compatibility
switch (f)
{
case XmlSchemaEnumerationFacet enumFacet:
@@ -429,8 +448,41 @@ namespace XSDVisualiser.Core
}
break;
}
+
+ // Always capture all facets generically for dynamic display
+ if (f is XmlSchemaFacet baseFacet)
+ {
+ var name = GetFacetName(f);
+ var value = baseFacet.Value;
+ if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
+ {
+ var exists = false;
+ foreach (var entry in cons.AllFacets)
+ {
+ if (string.Equals(entry.Name, name, StringComparison.Ordinal) && string.Equals(entry.Value, value, StringComparison.Ordinal))
+ {
+ exists = true; break;
+ }
+ }
+ if (!exists)
+ {
+ cons.AllFacets.Add(new FacetEntry { Name = name, Value = value });
+ }
+ }
+ }
}
}
+
+ private static string GetFacetName(XmlSchemaObject facet)
+ {
+ var typeName = facet.GetType().Name; // e.g., XmlSchemaMinInclusiveFacet
+ if (typeName.StartsWith("XmlSchema", StringComparison.Ordinal))
+ typeName = typeName.Substring("XmlSchema".Length);
+ if (typeName.EndsWith("Facet", StringComparison.Ordinal))
+ typeName = typeName.Substring(0, typeName.Length - "Facet".Length);
+ if (typeName.Length == 0) return typeName;
+ return char.ToLowerInvariant(typeName[0]) + typeName.Substring(1);
+ }
private static string? ExtractDocumentation(XmlSchemaAnnotated? annotated)
{
if (annotated?.Annotation == null) return null;