Removed old way of handling constraints

This commit is contained in:
Frederik Jacobsen 2025-10-18 21:48:30 +02:00
parent 838826e0ec
commit 8f3cbe7b5f
3 changed files with 21 additions and 206 deletions

View File

@ -58,71 +58,10 @@
<TextBlock Text="{Binding BaseTypeName}"/> <TextBlock Text="{Binding BaseTypeName}"/>
<StackPanel> <StackPanel>
<TextBlock Text="Enumerations" FontWeight="SemiBold"/> <TextBlock Text="Constraints" FontWeight="SemiBold"/>
<ItemsControl ItemsSource="{Binding Enumerations}" IsVisible="{Binding Enumerations, Converter={StaticResource HasItems}}"> <ItemsControl ItemsSource="{Binding Constraints}" IsVisible="{Binding Constraints, Converter={StaticResource HasItems}}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate x:DataType="x:String"> <DataTemplate x:DataType="m:ConstraintEntry">
<TextBlock Text="{Binding ., StringFormat=• {0}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel>
<TextBlock Text="Patterns" FontWeight="SemiBold"/>
<ItemsControl ItemsSource="{Binding Patterns}" IsVisible="{Binding Patterns, Converter={StaticResource HasItems}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{Binding ., StringFormat=• {0}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<!-- Numeric bounds -->
<StackPanel IsVisible="{Binding Numeric, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Numeric bounds" FontWeight="SemiBold"/>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MinInclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Min inclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MinInclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MaxInclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Max inclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MaxInclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MinExclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Min exclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MinExclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MaxExclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Max exclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MaxExclusive}"/>
</StackPanel>
</StackPanel>
<!-- Length bounds -->
<StackPanel IsVisible="{Binding Length, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Length bounds" FontWeight="SemiBold"/>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.LengthSpecified}">
<TextBlock Text="Length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.Length}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.MinLengthSpecified}">
<TextBlock Text="Min length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.MinLength}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.MaxLengthSpecified}">
<TextBlock Text="Max length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.MaxLength}"/>
</StackPanel>
</StackPanel>
<!-- Dynamic facets -->
<StackPanel>
<TextBlock Text="All facets" FontWeight="SemiBold"/>
<ItemsControl ItemsSource="{Binding AllFacets}" IsVisible="{Binding AllFacets, Converter={StaticResource HasItems}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="m:FacetEntry">
<TextBlock> <TextBlock>
<Run Text="• "/> <Run Text="• "/>
<Run Text="{Binding Name}"/> <Run Text="{Binding Name}"/>

View File

@ -117,68 +117,24 @@ namespace XSDVisualiser.Models
} }
/// <summary> /// <summary>
/// SimpleType constraints (facets). /// SimpleType constraints (formerly called facets).
/// </summary> /// </summary>
public class ConstraintSet public class ConstraintSet
{ {
[XmlAttribute] [XmlAttribute]
public string? BaseTypeName { get; set; } public string? BaseTypeName { get; set; }
[XmlArray("Enumerations")] // Generic catch-all list of constraints for dynamic display and tooling
[XmlArrayItem("Value")] [XmlArray("Constraints")]
public List<string> Enumerations { get; set; } = new(); [XmlArrayItem("Constraint")]
public List<ConstraintEntry> Constraints { get; set; } = new();
[XmlArray("Patterns")]
[XmlArrayItem("Regex")]
public List<string> Patterns { get; set; } = new();
[XmlElement]
public NumericBounds? Numeric { get; set; }
[XmlElement]
public LengthBounds? Length { get; set; }
// Generic catch-all list of facets for dynamic display and tooling
[XmlArray("Facets")]
[XmlArrayItem("Facet")]
public List<FacetEntry> AllFacets { get; set; } = new();
} }
public class FacetEntry public class ConstraintEntry
{ {
[XmlAttribute] [XmlAttribute]
public string? Name { get; set; } public string? Name { get; set; }
[XmlAttribute] [XmlAttribute]
public string? Value { get; set; } public string? Value { get; set; }
} }
public class NumericBounds
{
[XmlAttribute]
public string? MinInclusive { get; set; }
[XmlAttribute]
public string? MaxInclusive { get; set; }
[XmlAttribute]
public string? MinExclusive { get; set; }
[XmlAttribute]
public string? MaxExclusive { get; set; }
}
public class LengthBounds
{
[XmlAttribute]
public int Length { get; set; }
[XmlIgnore]
public bool LengthSpecified { get; set; }
[XmlAttribute]
public int MinLength { get; set; }
[XmlIgnore]
public bool MinLengthSpecified { get; set; }
[XmlAttribute]
public int MaxLength { get; set; }
[XmlIgnore]
public bool MaxLengthSpecified { get; set; }
}
} }

View File

@ -310,7 +310,6 @@ namespace XSDVisualiser.Core
break; break;
case XmlSchemaSimpleTypeList list: case XmlSchemaSimpleTypeList list:
{ {
cons.Patterns.Add("(list)");
if (!list.ItemTypeName.IsEmpty) if (!list.ItemTypeName.IsEmpty)
{ {
var baseType = ResolveType(list.ItemTypeName); var baseType = ResolveType(list.ItemTypeName);
@ -325,7 +324,6 @@ namespace XSDVisualiser.Core
} }
case XmlSchemaSimpleTypeUnion union: case XmlSchemaSimpleTypeUnion union:
{ {
cons.Patterns.Add("(union)");
foreach (var memberType in union.BaseMemberTypes) foreach (var memberType in union.BaseMemberTypes)
{ {
if (memberType is { } mst) if (memberType is { } mst)
@ -345,111 +343,33 @@ namespace XSDVisualiser.Core
private static void Merge(ConstraintSet target, ConstraintSet? source) private static void Merge(ConstraintSet target, ConstraintSet? source)
{ {
if (source == null) return; 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 // Merge generic constraints (name + value de-duplication)
if (source.AllFacets != null) if (source.Constraints != null)
{ {
foreach (var sf in source.AllFacets) foreach (var sc in source.Constraints)
{ {
var exists = false; var exists = false;
foreach (var tf in target.AllFacets) foreach (var tc in target.Constraints)
{ {
if (string.Equals(tf.Name, sf.Name, StringComparison.Ordinal) && string.Equals(tf.Value, sf.Value, StringComparison.Ordinal)) if (string.Equals(tc.Name, sc.Name, StringComparison.Ordinal) && string.Equals(tc.Value, sc.Value, StringComparison.Ordinal))
{ {
exists = true; break; exists = true; break;
} }
} }
if (!exists) target.AllFacets.Add(new FacetEntry { Name = sf.Name, Value = sf.Value }); if (!exists)
}
}
if (source.Numeric != null)
{ {
target.Numeric ??= new NumericBounds(); target.Constraints.Add(new ConstraintEntry { Name = sc.Name, Value = sc.Value });
target.Numeric.MinInclusive ??= source.Numeric.MinInclusive;
target.Numeric.MaxInclusive ??= source.Numeric.MaxInclusive;
target.Numeric.MinExclusive ??= source.Numeric.MinExclusive;
target.Numeric.MaxExclusive ??= source.Numeric.MaxExclusive;
} }
if (source.Length == null) return;
target.Length ??= new LengthBounds();
if (source.Length.LengthSpecified && !target.Length.LengthSpecified)
{
target.Length.Length = source.Length.Length;
target.Length.LengthSpecified = true;
} }
if (source.Length.MinLengthSpecified && !target.Length.MinLengthSpecified)
{
target.Length.MinLength = source.Length.MinLength;
target.Length.MinLengthSpecified = true;
} }
if (!source.Length.MaxLengthSpecified || target.Length.MaxLengthSpecified) return;
target.Length.MaxLength = source.Length.MaxLength;
target.Length.MaxLengthSpecified = true;
} }
private static void MergeFacets(ConstraintSet cons, XmlSchemaObjectCollection facets) private static void MergeFacets(ConstraintSet cons, XmlSchemaObjectCollection facets)
{ {
foreach (var f in facets) foreach (var f in facets)
{ {
// Map known facets to strongly-typed buckets for backward compatibility // Capture all constraints generically for dynamic display
switch (f)
{
case XmlSchemaEnumerationFacet enumFacet:
cons.Enumerations.Add(enumFacet.Value);
break;
case XmlSchemaPatternFacet patternFacet:
cons.Patterns.Add(patternFacet.Value);
break;
case XmlSchemaMinInclusiveFacet minInc:
cons.Numeric ??= new NumericBounds();
cons.Numeric.MinInclusive = minInc.Value;
break;
case XmlSchemaMaxInclusiveFacet maxInc:
cons.Numeric ??= new NumericBounds();
cons.Numeric.MaxInclusive = maxInc.Value;
break;
case XmlSchemaMinExclusiveFacet minEx:
cons.Numeric ??= new NumericBounds();
cons.Numeric.MinExclusive = minEx.Value;
break;
case XmlSchemaMaxExclusiveFacet maxEx:
cons.Numeric ??= new NumericBounds();
cons.Numeric.MaxExclusive = maxEx.Value;
break;
case XmlSchemaLengthFacet len:
cons.Length ??= new LengthBounds();
if (int.TryParse(len.Value, out var l))
{
cons.Length.Length = l;
cons.Length.LengthSpecified = true;
}
break;
case XmlSchemaMinLengthFacet minLen:
cons.Length ??= new LengthBounds();
if (int.TryParse(minLen.Value, out var ml))
{
cons.Length.MinLength = ml;
cons.Length.MinLengthSpecified = true;
}
break;
case XmlSchemaMaxLengthFacet maxLen:
cons.Length ??= new LengthBounds();
if (int.TryParse(maxLen.Value, out var xl))
{
cons.Length.MaxLength = xl;
cons.Length.MaxLengthSpecified = true;
}
break;
}
// Always capture all facets generically for dynamic display
if (f is XmlSchemaFacet baseFacet) if (f is XmlSchemaFacet baseFacet)
{ {
var name = GetFacetName(f); var name = GetFacetName(f);
@ -457,7 +377,7 @@ namespace XSDVisualiser.Core
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
{ {
var exists = false; var exists = false;
foreach (var entry in cons.AllFacets) foreach (var entry in cons.Constraints)
{ {
if (string.Equals(entry.Name, name, StringComparison.Ordinal) && string.Equals(entry.Value, value, StringComparison.Ordinal)) if (string.Equals(entry.Name, name, StringComparison.Ordinal) && string.Equals(entry.Value, value, StringComparison.Ordinal))
{ {
@ -466,7 +386,7 @@ namespace XSDVisualiser.Core
} }
if (!exists) if (!exists)
{ {
cons.AllFacets.Add(new FacetEntry { Name = name, Value = value }); cons.Constraints.Add(new ConstraintEntry { Name = name, Value = value });
} }
} }
} }