diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs index b41f05be289cce..fa0194f1b84bfe 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs @@ -89,5 +89,15 @@ public static bool IgnoreObsoleteMembers return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.IgnoreObsoleteMembers", ref s_ignoreObsoleteMembers); } } + + private static int s_useLegacyEmptyXmlElementDeserialization; + public static bool UseLegacyEmptyXmlElementDeserialization + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return SwitchesHelpers.GetCachedSwitchValue("Switch.System.Xml.UseLegacyEmptyXmlElementDeserialization", ref s_useLegacyEmptyXmlElementDeserialization); + } + } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs index 79741d5e849316..2b727f317add58 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs @@ -905,6 +905,11 @@ protected XmlQualifiedName ReadElementQualifiedName() if (wrapped) { if (ReadNull()) return null; + if (!LocalAppContextSwitches.UseLegacyEmptyXmlElementDeserialization && _r.IsEmptyElement) + { + _r.Skip(); + return null; + } _r.ReadStartElement(); _r.MoveToContent(); if (_r.NodeType != XmlNodeType.EndElement) diff --git a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs index 5e57f747f5ce65..07f0e6816fb2d0 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs @@ -3666,4 +3666,32 @@ public static void SerializePrimitiveXmlTextAttributeOnDerivedClass() var actual = SerializeAndDeserialize(value, "5"); Assert.Equal(value.Number, actual.Number); } + + [Theory] + [InlineData(@"

text

Test
", "Test", true, "p", "text")] + [InlineData(@"Test", "Test", false, null, null)] + [InlineData(@"Test", "Test", false, null, null, false)] + [InlineData(@"Test", "Test", false, null, null, false)] + [InlineData(@"

text

Test
", "Test", true, "p", "text", true)] + [InlineData(@"Test", null, true, "Name", "Test", true)] + [InlineData(@"Test", "Test", false, null, null, true)] + public static void Xml_XmlElementMember_EmptyElement_SiblingNotConsumed(string xml, string? expectedName, bool expectDescription, string? expectedDescriptionName, string? expectedDescriptionInnerXml, bool? compatSwitch = null) + { + using (var appContextScope = compatSwitch.HasValue ? new XmlSerializerAppContextSwitchScope("Switch.System.Xml.UseLegacyEmptyXmlElementDeserialization", compatSwitch.Value) : null) + { + var serializer = new XmlSerializer(typeof(TypeWithXmlElementMemberAndSibling)); + TypeWithXmlElementMemberAndSibling obj = (TypeWithXmlElementMemberAndSibling)serializer.Deserialize(new StringReader(xml)); + Assert.Equal(expectedName, obj.Name); + if (expectDescription) + { + Assert.NotNull(obj.Description); + Assert.Equal(expectedDescriptionName, obj.Description.Name); + Assert.Equal(expectedDescriptionInnerXml, obj.Description.InnerXml); + } + else + { + Assert.Null(obj.Description); + } + } + } } diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs index cfd07e6603c24b..6303b4bf9f431f 100644 --- a/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs +++ b/src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs @@ -836,6 +836,12 @@ public WithListOfXElement(bool init) } } + public class TypeWithXmlElementMemberAndSibling + { + public XmlElement Description { get; set; } + public string Name { get; set; } + } + public class BaseType { public virtual string Name1 { get; set; }