diff --git a/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj b/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj index ee44441d..ec99af34 100644 --- a/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj +++ b/XmlSchemaClassGenerator.Tests/XmlSchemaClassGenerator.Tests.csproj @@ -71,6 +71,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -182,6 +185,21 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -471,4 +489,7 @@ PreserveNewest + + + \ No newline at end of file diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index 930b06fe..21ca0b06 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -10,6 +10,7 @@ using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; +using System.Xml.XPath; using Ganss.IO; using Microsoft.CodeAnalysis; using Microsoft.Xml.XMLGen; @@ -77,6 +78,7 @@ private IEnumerable ConvertXml(string name, string xsd, Generator genera const string TimePattern = @"xsd\time\time.xsd"; const string TableauPattern = @"xsd\ts-api\*.xsd"; const string VSTstPattern = @"xsd\vstst\vstst.xsd"; + const string BpmnPattern = @"xsd\bpmn\*.xsd"; // IATA test takes too long to perform every time @@ -366,6 +368,62 @@ void TestCompareToXsd(Type t1, Type t2, string file) } } + [Fact, TestPriority(1)] + [UseCulture("en-US")] + public void TestBpmn() + { + var assembly = Compiler.Generate("Bpmn", BpmnPattern, new Generator + { + DataAnnotationMode = DataAnnotationMode.All, + GenerateNullables = true, + MemberVisitor = (member, model) => { } + }); + Assert.NotNull(assembly); + + var type = assembly.GetTypes().SingleOrDefault(t => t.Name == "TDefinitions"); + Assert.NotNull(type); + + var serializer = new XmlSerializer(type); + serializer.UnknownNode += new XmlNodeEventHandler(UnknownNodeHandler); + serializer.UnknownAttribute += new XmlAttributeEventHandler(UnknownAttributeHandler); + var unknownNodeError = false; + var unknownAttrError = false; + + void UnknownNodeHandler(object sender, XmlNodeEventArgs e) + { + unknownNodeError = true; + } + + void UnknownAttributeHandler(object sender, XmlAttributeEventArgs e) + { + unknownAttrError = true; + } + + var xml = ReadXml("bpmnSimple"); + var reader = XmlReader.Create(new StringReader(xml)); + + var isDeserializable = serializer.CanDeserialize(reader); + Assert.True(isDeserializable); + + var deserializedObject = serializer.Deserialize(reader); + Assert.False(unknownNodeError); + Assert.False(unknownAttrError); + + var serializedXml = Serialize(serializer, deserializedObject, GetNamespacesFromSource(xml)); + File.WriteAllText("file.xml", serializedXml); + + var deserializedXml = serializer.Deserialize(new StringReader(serializedXml)); + AssertEx.Equal(deserializedObject, deserializedXml); + } + + private IDictionary GetNamespacesFromSource(string source) + { + XPathDocument doc = new XPathDocument(new StringReader(source)); + XPathNavigator namespaceNavigator = doc.CreateNavigator(); + namespaceNavigator.MoveToFollowing(XPathNodeType.Element); + return namespaceNavigator.GetNamespacesInScope(XmlNamespaceScope.All); + } + [Fact, TestPriority(3)] public void CanSerializeAndDeserializeAllExampleXmlFiles() { @@ -397,11 +455,21 @@ void TestRoundtrip(Type t, string file) } } - string Serialize(XmlSerializer serializer, object o) + string Serialize(XmlSerializer serializer, object o, IDictionary prefixToNsMap = null) { var sw = new StringWriter(); var ns = new XmlSerializerNamespaces(); - ns.Add("", null); + if (prefixToNsMap == null) + { + ns.Add("", null); + } + else + { + foreach (var ptns in prefixToNsMap) + { + ns.Add(ptns.Key, ptns.Value); + } + } serializer.Serialize(sw, o, ns); var serializedXml = sw.ToString(); return serializedXml; diff --git a/XmlSchemaClassGenerator.Tests/xml/bpmnSimple.xml b/XmlSchemaClassGenerator.Tests/xml/bpmnSimple.xml new file mode 100644 index 00000000..b4b8ece0 --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xml/bpmnSimple.xml @@ -0,0 +1,44 @@ + + + + + SequenceFlow_15dil8x + + + SequenceFlow_15dil8x + SequenceFlow_1k24n4s + + + SequenceFlow_1k24n4s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMN20.xsd b/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMN20.xsd new file mode 100644 index 00000000..d60695ca --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMN20.xsd @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMNDI.xsd b/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMNDI.xsd new file mode 100644 index 00000000..e2c2e8ea --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xsd/bpmn/BPMNDI.xsd @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.Tests/xsd/bpmn/DC.xsd b/XmlSchemaClassGenerator.Tests/xsd/bpmn/DC.xsd new file mode 100644 index 00000000..aa2832ef --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xsd/bpmn/DC.xsd @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.Tests/xsd/bpmn/DI.xsd b/XmlSchemaClassGenerator.Tests/xsd/bpmn/DI.xsd new file mode 100644 index 00000000..bfcc6cd2 --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xsd/bpmn/DI.xsd @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.Tests/xsd/bpmn/Semantic.xsd b/XmlSchemaClassGenerator.Tests/xsd/bpmn/Semantic.xsd new file mode 100644 index 00000000..319cee64 --- /dev/null +++ b/XmlSchemaClassGenerator.Tests/xsd/bpmn/Semantic.xsd @@ -0,0 +1,1562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/XmlSchemaClassGenerator/TypeModel.cs b/XmlSchemaClassGenerator/TypeModel.cs index 3a0e10fe..1bba53b6 100644 --- a/XmlSchemaClassGenerator/TypeModel.cs +++ b/XmlSchemaClassGenerator/TypeModel.cs @@ -1025,7 +1025,8 @@ private IEnumerable GetAttributes(bool isArray) { var derivedAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(XmlElementAttribute), Configuration.CodeTypeReferenceOptions), new CodeAttributeArgument(new CodePrimitiveExpression((derivedType.SubstitutionName ?? derivedType.XmlSchemaName).Name)), - new CodeAttributeArgument("Type", new CodeTypeOfExpression(derivedType.GetReferenceFor(OwningType.Namespace)))); + new CodeAttributeArgument("Type", new CodeTypeOfExpression(derivedType.GetReferenceFor(OwningType.Namespace))), + new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(derivedType.XmlSchemaName.Namespace))); if (Order != null) { derivedAttribute.Arguments.Add(new CodeAttributeArgument("Order", @@ -1056,19 +1057,23 @@ private IEnumerable GetAttributes(bool isArray) foreach (var attribute in attributes) { - if (XmlNamespace != null) + bool namespacePrecalculated = attribute.Arguments.OfType().Any(a => a.Name == "Namespace"); + if (!namespacePrecalculated) { - attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(XmlNamespace))); - } - else if (Form == XmlSchemaForm.Qualified) - { - attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(OwningType.XmlSchemaName.Namespace))); - } - else if (!IsAny) - { - attribute.Arguments.Add(new CodeAttributeArgument("Form", - new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(XmlSchemaForm), Configuration.CodeTypeReferenceOptions)), - "Unqualified"))); + if (XmlNamespace != null) + { + attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(XmlNamespace))); + } + else if (Form == XmlSchemaForm.Qualified) + { + attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(OwningType.XmlSchemaName.Namespace))); + } + else if (!IsAny) + { + attribute.Arguments.Add(new CodeAttributeArgument("Form", + new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(XmlSchemaForm), Configuration.CodeTypeReferenceOptions)), + "Unqualified"))); + } } if (IsNillable)