Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1576,9 +1576,7 @@ private static XmlSerializationCollectionFixupCallback GetCreateCollectionOfObje
{
if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type))
{
// https://github.com/dotnet/runtime/issues/1399:
// To Support Serializing XmlSchemaObject
throw new NotImplementedException(nameof(XmlSchemaObject));
DecodeName = false;
}

object? o = ReflectionCreateObject(structMapping.TypeDesc.Type!)!;
Expand Down Expand Up @@ -1812,10 +1810,24 @@ private static XmlSerializationCollectionFixupCallback GetCreateCollectionOfObje
{
MemberInfo[] memberInfos = o!.GetType().GetMember(member.Mapping.Name);
MemberInfo memberInfo = memberInfos[0];
object? collection = null;
SetCollectionObjectWithCollectionMember(ref collection, member.Collection, member.Mapping.TypeDesc!.Type!);
var setMemberValue = GetSetMemberValueDelegate(o, memberInfo.Name);
setMemberValue(o, collection);

// For read-only collection properties (no setter), add items directly to the existing
// collection instance returned by the getter. This matches what the IL-based serializer does.
if (memberInfo is PropertyInfo pi && pi.GetSetMethod(nonPublic: true) == null)
{
object? existingCollection = pi.GetValue(o);
if (existingCollection != null)
{
AddObjectsIntoTargetCollection(existingCollection, member.Collection, member.Mapping.TypeDesc!.Type!);
}
}
else
{
object? collection = null;
SetCollectionObjectWithCollectionMember(ref collection, member.Collection, member.Mapping.TypeDesc!.Type!);
var setMemberValue = GetSetMemberValueDelegate(o, memberInfo.Name);
setMemberValue(o, collection);
}
}

member.EnsureCollection?.Invoke(o!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,39 +76,4 @@ public static void XML_TypeWithFieldsOrdered()
Assert.Equal(value.StringField1, actual.StringField1);
Assert.Equal(value.StringField2, actual.StringField2);
}

// TODO - Move this test to XmlSerializerTests.RuntimeOnly.cs once #1399 is fixed for the ReflectionOnly serializer.
[Fact]
public static void Xml_XmlSchema()
{
var expectedXml = WithXmlHeader("<xsd:schema xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" elementFormDefault=\"qualified\" targetNamespace=\"http://example.com/my-schema\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <xsd:element name=\"MyElement\" type=\"xsd:string\" />\r\n <xsd:group name=\"MyGroup\">\r\n <xsd:sequence>\r\n <xsd:element name=\"Item1\" />\r\n <xsd:element name=\"Item2\" />\r\n </xsd:sequence>\r\n </xsd:group>\r\n</xsd:schema>");

XmlSchema schema = new XmlSchema
{
TargetNamespace = "http://example.com/my-schema",
ElementFormDefault = XmlSchemaForm.Qualified
};
schema.Items.Add(new XmlSchemaElement
{
Name = "MyElement",
SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
});
schema.Items.Add(new XmlSchemaGroup
{
Name = "MyGroup",
Particle = new XmlSchemaSequence
{
Items = { new XmlSchemaElement { Name = "Item1" }, new XmlSchemaElement { Name = "Item2" } }
}
});
schema.Namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
schema.Namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

var actual = SerializeAndDeserialize(schema, expectedXml, () => new XmlSerializer(typeof(XmlSchema)));

Assert.Equal(schema.TargetNamespace, actual.TargetNamespace);
Assert.Equal(schema.ElementFormDefault, actual.ElementFormDefault);
Assert.Equal(schema.Items.Count, actual.Items.Count);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,81 @@ public static void XML_XmlSchemaWithNamespacesWriteWithNamespaceManager()
schema.Write(memStream, new XmlNamespaceManager(new NameTable()));
}

[Fact]
public static void Xml_XmlSchema()
{
var expectedXml = WithXmlHeader("<xsd:schema xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" elementFormDefault=\"qualified\" targetNamespace=\"http://example.com/my-schema\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <xsd:element name=\"MyElement\" type=\"xsd:string\" />\r\n <xsd:group name=\"MyGroup\">\r\n <xsd:sequence>\r\n <xsd:element name=\"Item1\" />\r\n <xsd:element name=\"Item2\" />\r\n </xsd:sequence>\r\n </xsd:group>\r\n</xsd:schema>");

XmlSchema schema = new XmlSchema
{
TargetNamespace = "http://example.com/my-schema",
ElementFormDefault = XmlSchemaForm.Qualified
};
schema.Items.Add(new XmlSchemaElement
{
Name = "MyElement",
SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
});
schema.Items.Add(new XmlSchemaGroup
{
Name = "MyGroup",
Particle = new XmlSchemaSequence
{
Items = { new XmlSchemaElement { Name = "Item1" }, new XmlSchemaElement { Name = "Item2" } }
}
});
schema.Namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
schema.Namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

var actual = SerializeAndDeserialize(schema, expectedXml, () => new XmlSerializer(typeof(XmlSchema)));

Assert.Equal(schema.TargetNamespace, actual.TargetNamespace);
Assert.Equal(schema.ElementFormDefault, actual.ElementFormDefault);
Assert.Equal(schema.Items.Count, actual.Items.Count);
}

[Fact]
public static void XmlSchemaObject_RoundTrip()
{
// Verify that XmlSchemaObject-derived types can be deserialized with the reflection-based
// serializer. Previously a NotImplementedException was thrown during deserialization.
var element = new XmlSchemaElement
{
Name = "TestElement",
SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
};
var serializer = new XmlSerializer(typeof(XmlSchemaElement));
using var ms = new MemoryStream();
serializer.Serialize(ms, element);
ms.Position = 0;

var result = (XmlSchemaElement?)serializer.Deserialize(ms);
Assert.NotNull(result);
Assert.Equal("TestElement", result.Name);
Assert.Equal(new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema"), result.SchemaTypeName);
}

[Fact]
public static void XmlSchemaObject_RoundTrip_WithConstraintInReadOnlyCollection()
{
// Verify that items in read-only collection properties (like XmlSchemaElement.Constraints)
// are correctly round-tripped using the reflection-based serializer.
var element = new XmlSchemaElement { Name = "TestElement" };
element.Constraints.Add(new XmlSchemaKey { Name = "PrimaryKey" });

var serializer = new XmlSerializer(typeof(XmlSchemaElement));
using var ms = new MemoryStream();
serializer.Serialize(ms, element);
ms.Position = 0;

var result = (XmlSchemaElement?)serializer.Deserialize(ms);
Assert.NotNull(result);
Assert.Equal("TestElement", result.Name);
Assert.Equal(1, result.Constraints.Count);
var key = Assert.IsType<XmlSchemaKey>(result.Constraints[0]);
Assert.Equal("PrimaryKey", key.Name);
}

[Fact]
public static void Xml_XmlElementAsRoot()
{
Expand Down
Loading