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)