From f2c7ec0d9a0644435def2fbe2740e9c966cfde19 Mon Sep 17 00:00:00 2001 From: Frederik Jacobsen Date: Sat, 18 Oct 2025 16:30:38 +0200 Subject: [PATCH] Initial commit --- .gitignore | 5 + .idea/.idea.XSDVisualiser/.idea/.gitignore | 13 + .idea/.idea.XSDVisualiser/.idea/encodings.xml | 4 + .../.idea.XSDVisualiser/.idea/indexLayout.xml | 8 + .idea/.idea.XSDVisualiser/.idea/vcs.xml | 6 + XSDVisualiser.sln | 16 + XSDVisualiser/Models/XsdSchemaModel.cs | 153 +++++ XSDVisualiser/Parsing/XsdSchemaParser.cs | 351 +++++++++++ XSDVisualiser/Program.cs | 88 +++ .../SF2900/DistributionServiceMsg.xsd | 86 +++ .../DistributionServiceAnvenderV2.wsdl | 58 ++ .../DistributionServiceModtagerV2.wsdl | 56 ++ .../DistributionServiceMsgV2.xsd | 40 ++ .../DistributionServiceTypesV2.xsd | 550 ++++++++++++++++++ .../SF2900/sp/AuthorityContext_1.xsd | 22 + .../Rescources/SF2900/sp/CallContext_1.xsd | 38 ++ .../SF2900/sp/InvocationContext_1.xsd | 67 +++ .../Rescources/SF2900/sp/Kvittering_1.xsd | 70 +++ .../sp/ServiceplatformFaultMessage_1.wsdl | 18 + .../SF2900/sp/ServiceplatformFault_1.xsd | 27 + .../sp/TransportKvitteringFaultMessage_1.wsdl | 18 + .../Rescources/SF2900/sp/service.properties | 2 + .../wsdl/context/DistributionService.wsdl | 135 +++++ .../SF2900/wsdl/context/policies.wsdl | 40 ++ .../wsdl/token/DistributionService.wsdl | 135 +++++ .../SF2900/wsdl/token/policies.wsdl | 83 +++ .../SF2900/xsd/DistributionServiceTypes.xsd | 64 ++ XSDVisualiser/Utils/Serialization.cs | 36 ++ XSDVisualiser/XSDVisualiser.csproj | 10 + 29 files changed, 2199 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.idea.XSDVisualiser/.idea/.gitignore create mode 100644 .idea/.idea.XSDVisualiser/.idea/encodings.xml create mode 100644 .idea/.idea.XSDVisualiser/.idea/indexLayout.xml create mode 100644 .idea/.idea.XSDVisualiser/.idea/vcs.xml create mode 100644 XSDVisualiser.sln create mode 100644 XSDVisualiser/Models/XsdSchemaModel.cs create mode 100644 XSDVisualiser/Parsing/XsdSchemaParser.cs create mode 100644 XSDVisualiser/Program.cs create mode 100644 XSDVisualiser/Rescources/SF2900/DistributionServiceMsg.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceAnvenderV2.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceModtagerV2.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceMsgV2.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceTypesV2.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/AuthorityContext_1.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/CallContext_1.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/InvocationContext_1.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/Kvittering_1.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFaultMessage_1.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFault_1.xsd create mode 100644 XSDVisualiser/Rescources/SF2900/sp/TransportKvitteringFaultMessage_1.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/sp/service.properties create mode 100644 XSDVisualiser/Rescources/SF2900/wsdl/context/DistributionService.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/wsdl/context/policies.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/wsdl/token/DistributionService.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/wsdl/token/policies.wsdl create mode 100644 XSDVisualiser/Rescources/SF2900/xsd/DistributionServiceTypes.xsd create mode 100644 XSDVisualiser/Utils/Serialization.cs create mode 100644 XSDVisualiser/XSDVisualiser.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..add57be --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ \ No newline at end of file diff --git a/.idea/.idea.XSDVisualiser/.idea/.gitignore b/.idea/.idea.XSDVisualiser/.idea/.gitignore new file mode 100644 index 0000000..209e471 --- /dev/null +++ b/.idea/.idea.XSDVisualiser/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/.idea.XSDVisualiser.iml +/projectSettingsUpdater.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.XSDVisualiser/.idea/encodings.xml b/.idea/.idea.XSDVisualiser/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.XSDVisualiser/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.XSDVisualiser/.idea/indexLayout.xml b/.idea/.idea.XSDVisualiser/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.XSDVisualiser/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.XSDVisualiser/.idea/vcs.xml b/.idea/.idea.XSDVisualiser/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.XSDVisualiser/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/XSDVisualiser.sln b/XSDVisualiser.sln new file mode 100644 index 0000000..bbb2857 --- /dev/null +++ b/XSDVisualiser.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XSDVisualiser", "XSDVisualiser\XSDVisualiser.csproj", "{A42F0483-69BE-44FC-8147-DA3466375051}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A42F0483-69BE-44FC-8147-DA3466375051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A42F0483-69BE-44FC-8147-DA3466375051}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A42F0483-69BE-44FC-8147-DA3466375051}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A42F0483-69BE-44FC-8147-DA3466375051}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/XSDVisualiser/Models/XsdSchemaModel.cs b/XSDVisualiser/Models/XsdSchemaModel.cs new file mode 100644 index 0000000..8d4c050 --- /dev/null +++ b/XSDVisualiser/Models/XsdSchemaModel.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace XSDVisualiser.Models +{ + /// + /// Root of the parsed XSD representation. + /// + [XmlRoot("SchemaModel")] + public class SchemaModel + { + [XmlAttribute] + public string? TargetNamespace { get; set; } + + [XmlArray("RootElements")] + [XmlArrayItem("Element")] + public List RootElements { get; set; } = new(); + } + + /// + /// Represents an element or complex content node in the schema. + /// + public class SchemaNode + { + [XmlAttribute] + public string? Name { get; set; } + + [XmlAttribute] + public string? Namespace { get; set; } + + [XmlAttribute] + public string? TypeName { get; set; } + + [XmlAttribute] + public string? BuiltInType { get; set; } + + [XmlAttribute] + public bool IsNillable { get; set; } + + [XmlElement] + public Occurs Cardinality { get; set; } = new(); + + [XmlElement] + public ConstraintSet? Constraints { get; set; } + + [XmlArray("Attributes")] + [XmlArrayItem("Attribute")] + public List Attributes { get; set; } = new(); + + [XmlArray("Children")] + [XmlArrayItem("Element")] + public List Children { get; set; } = new(); + + [XmlAttribute] + public string? ContentModel { get; set; } // sequence | choice | all | simple + } + + /// + /// Min/Max occurrences. + /// + public class Occurs + { + [XmlAttribute] + public decimal Min { get; set; } = 1; + + /// + /// If MaxIsUnbounded is true, Max is ignored. + /// + [XmlAttribute] + public decimal Max { get; set; } = 1; + + [XmlAttribute] + public bool MaxIsUnbounded { get; set; } + } + + /// + /// Attribute definition extracted from XSD. + /// + public class AttributeInfo + { + [XmlAttribute] + public string? Name { get; set; } + + [XmlAttribute] + public string? Namespace { get; set; } + + [XmlAttribute] + public string? Use { get; set; } // optional | required | prohibited + + [XmlAttribute] + public string? TypeName { get; set; } + + [XmlAttribute] + public string? BuiltInType { get; set; } + + [XmlElement] + public ConstraintSet? Constraints { get; set; } + } + + /// + /// SimpleType constraints (facets). + /// + public class ConstraintSet + { + [XmlAttribute] + public string? BaseTypeName { get; set; } + + [XmlArray("Enumerations")] + [XmlArrayItem("Value")] + public List Enumerations { get; set; } = new(); + + [XmlArray("Patterns")] + [XmlArrayItem("Regex")] + public List Patterns { get; set; } = new(); + + [XmlElement] + public NumericBounds? Numeric { get; set; } + + [XmlElement] + public LengthBounds? Length { 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; } + } +} diff --git a/XSDVisualiser/Parsing/XsdSchemaParser.cs b/XSDVisualiser/Parsing/XsdSchemaParser.cs new file mode 100644 index 0000000..6720b66 --- /dev/null +++ b/XSDVisualiser/Parsing/XsdSchemaParser.cs @@ -0,0 +1,351 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using System.Xml.Schema; +using XSDVisualiser.Models; + +namespace XSDVisualiser.Parsing +{ + public class XsdSchemaParser + { + private readonly XmlSchemaSet _set = new(); + + public SchemaModel Parse(string xsdPath) + { + _set.XmlResolver = new XmlUrlResolver(); + using var reader = XmlReader.Create(xsdPath, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); + var schema = XmlSchema.Read(reader, ValidationCallback); + _set.Add(schema); + _set.CompilationSettings = new XmlSchemaCompilationSettings { EnableUpaCheck = true }; + _set.Compile(); + + var model = new SchemaModel + { + TargetNamespace = schema.TargetNamespace + }; + + foreach (XmlSchemaElement globalEl in _set.Schemas().Cast() + .SelectMany(s => s.Elements.Values.Cast())) + { + var node = BuildNodeForElement(globalEl, parentContentModel: null); + model.RootElements.Add(node); + } + + return model; + } + + 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}"); + } + + private SchemaNode BuildNodeForElement(XmlSchemaElement element, string? parentContentModel) + { + var node = new SchemaNode + { + Name = element.Name ?? element.RefName.Name, + Namespace = (element.QualifiedName.IsEmpty ? element.RefName : element.QualifiedName).Namespace, + IsNillable = element.IsNillable, + Cardinality = new Occurs + { + Min = element.MinOccurs, + Max = element.MaxOccurs, + MaxIsUnbounded = element.MaxOccursString == "unbounded" + }, + ContentModel = parentContentModel + }; + + var type = ResolveElementType(element); + if (type != null) + { + node.TypeName = GetQualifiedTypeName(type); + if (type.Datatype != null) + { + node.BuiltInType = type.Datatype.TypeCode.ToString(); + } + + switch (type) + { + case XmlSchemaComplexType ct: + HandleComplexType(node, ct); + break; + case XmlSchemaSimpleType st: + node.ContentModel = "simple"; + node.Constraints = ExtractConstraints(st); + break; + } + } + + return node; + } + + private static string? GetQualifiedTypeName(XmlSchemaType type) + { + if (!type.QualifiedName.IsEmpty) return type.QualifiedName.ToString(); + return type.BaseXmlSchemaType != null && !type.BaseXmlSchemaType.QualifiedName.IsEmpty + ? type.BaseXmlSchemaType.QualifiedName.ToString() + : type.Name; + } + + private XmlSchemaType? ResolveElementType(XmlSchemaElement el) + { + if (el.ElementSchemaType != null) return el.ElementSchemaType; + if (!el.SchemaTypeName.IsEmpty) + { + return _set.GlobalTypes[el.SchemaTypeName] as XmlSchemaType; + } + if (el.SchemaType != null) return el.SchemaType; + return null; + } + + private void HandleComplexType(SchemaNode node, XmlSchemaComplexType ct) + { + // Attributes + foreach (XmlSchemaAttribute attr in ct.AttributeUses.Values.OfType()) + { + node.Attributes.Add(ExtractAttribute(attr)); + } + + // Content model + if (ct.ContentTypeParticle is XmlSchemaGroupBase group) + { + var content = group switch + { + XmlSchemaSequence => "sequence", + XmlSchemaChoice => "choice", + XmlSchemaAll => "all", + _ => "group" + }; + node.ContentModel = content; + + foreach (var item in group.Items) + { + switch (item) + { + case XmlSchemaElement childEl: + node.Children.Add(BuildNodeForElement(childEl, content)); + break; + case XmlSchemaGroupBase nestedGroup: + // Flatten nested groups by introducing synthetic nodes + var synthetic = new SchemaNode + { + Name = "(group)", + Namespace = node.Namespace, + ContentModel = nestedGroup switch + { + XmlSchemaSequence => "sequence", + XmlSchemaChoice => "choice", + XmlSchemaAll => "all", + _ => "group" + }, + Cardinality = new Occurs { Min = nestedGroup.MinOccurs, Max = nestedGroup.MaxOccurs, MaxIsUnbounded = nestedGroup.MaxOccursString == "unbounded" } + }; + foreach (var nestedItem in nestedGroup.Items) + { + if (nestedItem is XmlSchemaElement ngChild) + { + synthetic.Children.Add(BuildNodeForElement(ngChild, synthetic.ContentModel)); + } + } + node.Children.Add(synthetic); + break; + // Skip other particles for now + } + } + } + else if (ct.ContentType == XmlSchemaContentType.TextOnly && ct.ContentModel is XmlSchemaSimpleContent simpleContent) + { + node.ContentModel = "simple"; + if (simpleContent.Content is XmlSchemaSimpleContentExtension ext) + { + var baseType = ResolveType(ext.BaseTypeName); + if (baseType is XmlSchemaSimpleType st) + { + node.Constraints = ExtractConstraints(st); + node.TypeName ??= GetQualifiedTypeName(st); + node.BuiltInType ??= st.Datatype?.TypeCode.ToString(); + } + + foreach (XmlSchemaAttribute attr in ext.Attributes.OfType()) + { + node.Attributes.Add(ExtractAttribute(attr)); + } + } + else if (simpleContent.Content is XmlSchemaSimpleContentRestriction res) + { + var baseType = ResolveType(res.BaseTypeName); + if (baseType is XmlSchemaSimpleType st) + { + var cons = ExtractConstraints(st); + MergeFacets(cons, res.Facets); + node.Constraints = cons; + node.TypeName ??= GetQualifiedTypeName(st); + node.BuiltInType ??= st.Datatype?.TypeCode.ToString(); + } + } + } + } + + private XmlSchemaType? ResolveType(XmlQualifiedName qname) + { + if (qname.IsEmpty) return null; + return _set.GlobalTypes[qname] as XmlSchemaType; + } + + private AttributeInfo ExtractAttribute(XmlSchemaAttribute attr) + { + var info = new AttributeInfo + { + Name = attr.Name ?? attr.RefName.Name, + Namespace = (attr.QualifiedName.IsEmpty ? attr.RefName : attr.QualifiedName).Namespace, + Use = attr.Use.ToString() + }; + + XmlSchemaSimpleType? st = null; + if (attr.AttributeSchemaType != null) st = attr.AttributeSchemaType as XmlSchemaSimpleType; + else if (!attr.SchemaTypeName.IsEmpty) st = ResolveType(attr.SchemaTypeName) as XmlSchemaSimpleType; + else if (attr.SchemaType != null) st = attr.SchemaType; + + if (st != null) + { + info.TypeName = GetQualifiedTypeName(st); + info.BuiltInType = st.Datatype?.TypeCode.ToString(); + info.Constraints = ExtractConstraints(st); + } + + return info; + } + + private ConstraintSet? ExtractConstraints(XmlSchemaSimpleType st) + { + var cons = new ConstraintSet + { + BaseTypeName = GetQualifiedTypeName(st.BaseXmlSchemaType) + }; + + if (st.Content is XmlSchemaSimpleTypeRestriction restr) + { + MergeFacets(cons, restr.Facets); + } + else if (st.Content is XmlSchemaSimpleTypeList list) + { + cons.Patterns.Add("(list)"); + if (!list.ItemTypeName.IsEmpty) + { + var baseType = ResolveType(list.ItemTypeName); + if (baseType is XmlSchemaSimpleType itemSt) + { + var sub = ExtractConstraints(itemSt); + Merge(cons, sub); + } + } + } + else if (st.Content is XmlSchemaSimpleTypeUnion union) + { + cons.Patterns.Add("(union)"); + foreach (var memberType in union.BaseMemberTypes) + { + if (memberType is XmlSchemaSimpleType mst) + { + var sub = ExtractConstraints(mst); + Merge(cons, sub); + } + } + } + + return cons; + } + + private static void Merge(ConstraintSet target, ConstraintSet? source) + { + if (source == null) return; + foreach (var e in source.Enumerations) if (!target.Enumerations.Contains(e)) target.Enumerations.Add(e); + foreach (var p in source.Patterns) if (!target.Patterns.Contains(p)) target.Patterns.Add(p); + if (source.Numeric != null) + { + target.Numeric ??= new NumericBounds(); + 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) + { + 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) + { + target.Length.MaxLength = source.Length.MaxLength; + target.Length.MaxLengthSpecified = true; + } + } + } + + private static void MergeFacets(ConstraintSet cons, XmlSchemaObjectCollection facets) + { + foreach (var f in facets) + { + 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; + } + } + } + } +} diff --git a/XSDVisualiser/Program.cs b/XSDVisualiser/Program.cs new file mode 100644 index 0000000..a59fe62 --- /dev/null +++ b/XSDVisualiser/Program.cs @@ -0,0 +1,88 @@ +using XSDVisualiser.Parsing; +using XSDVisualiser.Utils; + +/* +if (args.Length == 0 || args[0] is "-h" or "--help") +{ + PrintHelp(); + return; +} +var inputPath = args[0]; +*/ + +const string inputPath = "/home/frederik/Work/XSDVisualiser/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceMsgV2.xsd"; + +if (!File.Exists(inputPath)) +{ + Console.Error.WriteLine($"Input XSD file not found: {inputPath}"); + Environment.Exit(1); +} + +var format = "json"; +string? outPath = null; +for (int i = 1; i < args.Length; i++) +{ + switch (args[i]) + { + case "--format": + if (i + 1 < args.Length) + { + format = args[++i].ToLowerInvariant(); + } + else + { + Console.Error.WriteLine("--format requires a value: xml or json"); + Environment.Exit(2); + } + break; + case "--out": + if (i + 1 < args.Length) + { + outPath = args[++i]; + } + else + { + Console.Error.WriteLine("--out requires a file path"); + Environment.Exit(2); + } + break; + } +} + +try +{ + var parser = new XsdSchemaParser(); + var model = parser.Parse(inputPath); + + string output = format switch + { + "json" => Serialization.ToJson(model), + _ => Serialization.ToXml(model) + }; + + if (!string.IsNullOrWhiteSpace(outPath)) + { + File.WriteAllText(outPath!, output); + Console.WriteLine($"Wrote {format.ToUpperInvariant()} to {Path.GetFullPath(outPath!)}"); + } + else + { + Console.WriteLine(output); + } +} +catch (Exception ex) +{ + Console.Error.WriteLine("Error: " + ex.ToString()); + if (ex.InnerException != null) + { + Console.Error.WriteLine("Inner: " + ex.InnerException.ToString()); + } + Environment.Exit(3); +} + +static void PrintHelp() +{ + Console.WriteLine("XSDVisualiser - Parse an XSD and emit a structural model with types, constraints, and cardinality"); + Console.WriteLine("Usage: XSDVisualiser [--format xml|json] [--out outputFile]"); + Console.WriteLine("Default format is xml; if --out is omitted the output is printed to stdout."); +} \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/DistributionServiceMsg.xsd b/XSDVisualiser/Rescources/SF2900/DistributionServiceMsg.xsd new file mode 100644 index 0000000..6cdb416 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/DistributionServiceMsg.xsd @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceAnvenderV2.wsdl b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceAnvenderV2.wsdl new file mode 100644 index 0000000..dbb871d --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceAnvenderV2.wsdl @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceModtagerV2.wsdl b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceModtagerV2.wsdl new file mode 100644 index 0000000..6085055 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceModtagerV2.wsdl @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceMsgV2.xsd b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceMsgV2.xsd new file mode 100644 index 0000000..3b5fea8 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceMsgV2.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceTypesV2.xsd b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceTypesV2.xsd new file mode 100644 index 0000000..fd68015 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/SF2900_EP_MS1-2/DistributionServiceTypesV2.xsd @@ -0,0 +1,550 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/sp/AuthorityContext_1.xsd b/XSDVisualiser/Rescources/SF2900/sp/AuthorityContext_1.xsd new file mode 100644 index 0000000..964e341 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/AuthorityContext_1.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/sp/CallContext_1.xsd b/XSDVisualiser/Rescources/SF2900/sp/CallContext_1.xsd new file mode 100644 index 0000000..263b291 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/CallContext_1.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/sp/InvocationContext_1.xsd b/XSDVisualiser/Rescources/SF2900/sp/InvocationContext_1.xsd new file mode 100644 index 0000000..8793b46 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/InvocationContext_1.xsd @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/sp/Kvittering_1.xsd b/XSDVisualiser/Rescources/SF2900/sp/Kvittering_1.xsd new file mode 100644 index 0000000..f955a0a --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/Kvittering_1.xsd @@ -0,0 +1,70 @@ + + + + + + Version 1.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFaultMessage_1.wsdl b/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFaultMessage_1.wsdl new file mode 100644 index 0000000..0adde52 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFaultMessage_1.wsdl @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFault_1.xsd b/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFault_1.xsd new file mode 100644 index 0000000..ad5420e --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/ServiceplatformFault_1.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/sp/TransportKvitteringFaultMessage_1.wsdl b/XSDVisualiser/Rescources/SF2900/sp/TransportKvitteringFaultMessage_1.wsdl new file mode 100644 index 0000000..1ef460f --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/TransportKvitteringFaultMessage_1.wsdl @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/sp/service.properties b/XSDVisualiser/Rescources/SF2900/sp/service.properties new file mode 100644 index 0000000..90081d7 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/sp/service.properties @@ -0,0 +1,2 @@ +service.uuid=74d3c5f5-1b3c-4c6d-8366-1241f055d332 +service.entityID=http://sp.serviceplatformen.dk/service/fordeling/3 \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/wsdl/context/DistributionService.wsdl b/XSDVisualiser/Rescources/SF2900/wsdl/context/DistributionService.wsdl new file mode 100644 index 0000000..1070c3a --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/wsdl/context/DistributionService.wsdl @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/wsdl/context/policies.wsdl b/XSDVisualiser/Rescources/SF2900/wsdl/context/policies.wsdl new file mode 100644 index 0000000..3a3ba98 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/wsdl/context/policies.wsdl @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/wsdl/token/DistributionService.wsdl b/XSDVisualiser/Rescources/SF2900/wsdl/token/DistributionService.wsdl new file mode 100644 index 0000000..1070c3a --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/wsdl/token/DistributionService.wsdl @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Rescources/SF2900/wsdl/token/policies.wsdl b/XSDVisualiser/Rescources/SF2900/wsdl/token/policies.wsdl new file mode 100644 index 0000000..655cbd7 --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/wsdl/token/policies.wsdl @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XSDVisualiser/Rescources/SF2900/xsd/DistributionServiceTypes.xsd b/XSDVisualiser/Rescources/SF2900/xsd/DistributionServiceTypes.xsd new file mode 100644 index 0000000..147e25a --- /dev/null +++ b/XSDVisualiser/Rescources/SF2900/xsd/DistributionServiceTypes.xsd @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XSDVisualiser/Utils/Serialization.cs b/XSDVisualiser/Utils/Serialization.cs new file mode 100644 index 0000000..294360e --- /dev/null +++ b/XSDVisualiser/Utils/Serialization.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Xml.Serialization; + +namespace XSDVisualiser.Utils +{ + public static class Serialization + { + public static string ToXml(T obj) + { + var serializer = new XmlSerializer(typeof(T)); + var ns = new XmlSerializerNamespaces(); + ns.Add(string.Empty, string.Empty); + using var sw = new Utf8StringWriter(); + serializer.Serialize(sw, obj, ns); + return sw.ToString(); + } + + public static string ToJson(T obj) + { + var options = new JsonSerializerOptions + { + WriteIndented = true, + DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull + }; + return JsonSerializer.Serialize(obj, options); + } + + private sealed class Utf8StringWriter : StringWriter + { + public override Encoding Encoding => Encoding.UTF8; + } + } +} diff --git a/XSDVisualiser/XSDVisualiser.csproj b/XSDVisualiser/XSDVisualiser.csproj new file mode 100644 index 0000000..85b4959 --- /dev/null +++ b/XSDVisualiser/XSDVisualiser.csproj @@ -0,0 +1,10 @@ + + + + Exe + net9.0 + enable + enable + + +