👻

.NET 6 と .NET 5 でXmlSerializerを用いたXML出力結果が異なる

2021/11/25に公開

概要

XmlSerializerを使用して出力したXMLが、.NET 6 と .NET 5で異なっていた
.NET 5では、整形された状態で出力されていたのに.NET 6では整形されていなかった
(改行インデント無しの一行で出力)

原因

.NET 5 と.NET 6でこの辺のコードに変更があった
変更理由はパフォーマンス改善が理由らしい
https://github.com/dotnet/runtime/pull/56524

.NET のコード確認

https://github.com/dotnet/runtime/blob/release/5.0/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs#L299
https://github.com/dotnet/runtime/blob/release/6.0/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs#L337

[参考] 実際のXML出力結果

.NET 6

<?xml version="1.0" encoding="utf-16"?><ClassA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ClassB><cbVal>123</cbVal><cbStr>strClassB</cbStr></ClassB><Val>456</Val><Str>strClassA</Str><ValList><int>7</int><int>8</int><int>9</int></ValList><StrList><string>a</string><string>b</string><string>c</string></StrList></ClassA>

.NET 5

<?xml version="1.0" encoding="utf-16"?>
<ClassA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ClassB>
    <cbVal>123</cbVal>
    <cbStr>strClassB</cbStr>
  </ClassB>
  <Val>456</Val>
  <Str>strClassA</Str>
  <ValList>
    <int>7</int>
    <int>8</int>
    <int>9</int>
  </ValList>
  <StrList>
    <string>a</string>
    <string>b</string>
    <string>c</string>
  </StrList>
</ClassA>

実験用コード(一部抜粋)

var serializer = new XmlSerializer(typeof(ClassA));
using (var stringWriter = new StringWriter())
{
    serializer.Serialize(stringWriter, obj);
    File.WriteAllText("dotNET6xml.xml", stringWriter.ToString());
}

https://github.com/yukg/serialize_sample

Discussion