diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs
index 0f69ef093c0f8..508a8fa50abbe 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs
@@ -430,13 +430,18 @@ internal override void WriteStartNamespaceDeclaration(string prefix)
if (_trackTextContent && _inTextContent) { ChangeTextContentMark(false); }
+ if (_attrEndPos == _bufPos)
+ {
+ _bufChars[_bufPos++] = (char)' ';
+ }
+
if (prefix.Length == 0)
{
- RawText(" xmlns=\"");
+ RawText("xmlns=\"");
}
else
{
- RawText(" xmlns:");
+ RawText("xmlns:");
RawText(prefix);
_bufChars[_bufPos++] = (char)'=';
_bufChars[_bufPos++] = (char)'"';
@@ -2037,6 +2042,18 @@ public override void WriteStartAttribute(string? prefix, string localName, strin
base.WriteStartAttribute(prefix, localName, ns);
}
+ // Same as base class, plus possible indentation.
+ internal override void WriteStartNamespaceDeclaration(string prefix)
+ {
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ WriteIndent();
+ }
+
+ base.WriteStartNamespaceDeclaration(prefix);
+ }
+
public override void WriteCData(string? text)
{
_mixedContent = true;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs
index f622c159d9f97..6ca97ede3105e 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs
@@ -318,13 +318,18 @@ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
if (_trackTextContent && _inTextContent) { ChangeTextContentMark(false); }
+ if (_attrEndPos == _bufPos)
+ {
+ _bufChars[_bufPos++] = (char)' ';
+ }
+
if (prefix.Length == 0)
{
- await RawTextAsync(" xmlns=\"").ConfigureAwait(false);
+ await RawTextAsync("xmlns=\"").ConfigureAwait(false);
}
else
{
- await RawTextAsync(" xmlns:").ConfigureAwait(false);
+ await RawTextAsync("xmlns:").ConfigureAwait(false);
await RawTextAsync(prefix).ConfigureAwait(false);
_bufChars[_bufPos++] = (char)'=';
_bufChars[_bufPos++] = (char)'"';
@@ -1976,6 +1981,19 @@ protected internal override async Task WriteStartAttributeAsync(string? prefix,
await base.WriteStartAttributeAsync(prefix, localName, ns).ConfigureAwait(false);
}
+ // Same as base class, plus possible indentation.
+ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
+ {
+ CheckAsyncCall();
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ await WriteIndentAsync().ConfigureAwait(false);
+ }
+
+ await base.WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+ }
+
public override Task WriteCDataAsync(string? text)
{
CheckAsyncCall();
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude
index e79b7ff1f00c2..61d85043919b0 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude
@@ -458,13 +458,18 @@ namespace System.Xml
#><#= SetTextContentMark(3, false) #>
+ if (_attrEndPos == _bufPos)
+ {
+ <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' ';
+ }
+
if (prefix.Length == 0)
{
- RawText(" xmlns=\"");
+ RawText("xmlns=\"");
}
else
{
- RawText(" xmlns:");
+ RawText("xmlns:");
RawText(prefix);
<#= BufferName #>[_bufPos++] = (<#= BufferType #>)'=';
<#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"';
@@ -2090,6 +2095,18 @@ namespace System.Xml
base.WriteStartAttribute(prefix, localName, ns);
}
+ // Same as base class, plus possible indentation.
+ internal override void WriteStartNamespaceDeclaration(string prefix)
+ {
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ WriteIndent();
+ }
+
+ base.WriteStartNamespaceDeclaration(prefix);
+ }
+
public override void WriteCData(string text)
{
_mixedContent = true;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude
index f12e1e53cb77f..638ee0f401e67 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude
@@ -321,13 +321,18 @@ namespace System.Xml
#><#= SetTextContentMark(3, false) #>
+ if (_attrEndPos == _bufPos)
+ {
+ <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' ';
+ }
+
if (prefix.Length == 0)
{
- await RawTextAsync(" xmlns=\"").ConfigureAwait(false);
+ await RawTextAsync("xmlns=\"").ConfigureAwait(false);
}
else
{
- await RawTextAsync(" xmlns:").ConfigureAwait(false);
+ await RawTextAsync("xmlns:").ConfigureAwait(false);
await RawTextAsync(prefix).ConfigureAwait(false);
<#= BufferName #>[_bufPos++] = (<#= BufferType #>)'=';
<#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"';
@@ -1919,6 +1924,19 @@ namespace System.Xml
await base.WriteStartAttributeAsync(prefix, localName, ns).ConfigureAwait(false);
}
+ // Same as base class, plus possible indentation.
+ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
+ {
+ CheckAsyncCall();
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ await WriteIndentAsync().ConfigureAwait(false);
+ }
+
+ await base.WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+ }
+
public override Task WriteCDataAsync(string text)
{
CheckAsyncCall();
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs
index b97fb5f2742dd..6f5ada6cab1f9 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs
@@ -363,13 +363,18 @@ internal override void WriteStartNamespaceDeclaration(string prefix)
{
Debug.Assert(prefix != null);
+ if (_attrEndPos == _bufPos)
+ {
+ _bufBytes[_bufPos++] = (byte)' ';
+ }
+
if (prefix.Length == 0)
{
- RawText(" xmlns=\"");
+ RawText("xmlns=\"");
}
else
{
- RawText(" xmlns:");
+ RawText("xmlns:");
RawText(prefix);
_bufBytes[_bufPos++] = (byte)'=';
_bufBytes[_bufPos++] = (byte)'"';
@@ -1894,6 +1899,18 @@ public override void WriteStartAttribute(string? prefix, string localName, strin
base.WriteStartAttribute(prefix, localName, ns);
}
+ // Same as base class, plus possible indentation.
+ internal override void WriteStartNamespaceDeclaration(string prefix)
+ {
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ WriteIndent();
+ }
+
+ base.WriteStartNamespaceDeclaration(prefix);
+ }
+
public override void WriteCData(string? text)
{
_mixedContent = true;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs
index 84e3cc4fa7bcd..09d68c92ecb9a 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs
@@ -282,13 +282,18 @@ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
CheckAsyncCall();
Debug.Assert(prefix != null);
+ if (_attrEndPos == _bufPos)
+ {
+ _bufBytes[_bufPos++] = (byte)' ';
+ }
+
if (prefix.Length == 0)
{
- await RawTextAsync(" xmlns=\"").ConfigureAwait(false);
+ await RawTextAsync("xmlns=\"").ConfigureAwait(false);
}
else
{
- await RawTextAsync(" xmlns:").ConfigureAwait(false);
+ await RawTextAsync("xmlns:").ConfigureAwait(false);
await RawTextAsync(prefix).ConfigureAwait(false);
_bufBytes[_bufPos++] = (byte)'=';
_bufBytes[_bufPos++] = (byte)'"';
@@ -1841,6 +1846,19 @@ protected internal override async Task WriteStartAttributeAsync(string? prefix,
await base.WriteStartAttributeAsync(prefix, localName, ns).ConfigureAwait(false);
}
+ // Same as base class, plus possible indentation.
+ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix)
+ {
+ CheckAsyncCall();
+ // Add indentation
+ if (_newLineOnAttributes)
+ {
+ await WriteIndentAsync().ConfigureAwait(false);
+ }
+
+ await base.WriteStartNamespaceDeclarationAsync(prefix).ConfigureAwait(false);
+ }
+
public override Task WriteCDataAsync(string? text)
{
CheckAsyncCall();
diff --git a/src/libraries/System.Private.Xml/tests/System.Private.Xml.Tests.csproj b/src/libraries/System.Private.Xml/tests/System.Private.Xml.Tests.csproj
index f0765630d8d63..d349b820a32b8 100644
--- a/src/libraries/System.Private.Xml/tests/System.Private.Xml.Tests.csproj
+++ b/src/libraries/System.Private.Xml/tests/System.Private.Xml.Tests.csproj
@@ -254,7 +254,6 @@
-
PreserveNewest
@@ -326,6 +325,7 @@
+
@@ -437,6 +437,7 @@
+
diff --git a/src/libraries/System.Private.Xml/tests/XmlWriter/WriteWithXmlnsNewLine.cs b/src/libraries/System.Private.Xml/tests/XmlWriter/WriteWithXmlnsNewLine.cs
new file mode 100644
index 0000000000000..cd18ebb741164
--- /dev/null
+++ b/src/libraries/System.Private.Xml/tests/XmlWriter/WriteWithXmlnsNewLine.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace System.Xml.XmlWriterTests
+{
+ public class XmlWriterTests_XmlnsNewLine
+ {
+ [Fact]
+ public static void WriteWithXmlnsNewLine()
+ {
+ XmlDocument xml = new();
+ xml.LoadXml("");
+
+ XmlWriterSettings settings = new();
+ settings.NewLineOnAttributes = true;
+ settings.NewLineChars = "\n";
+ settings.Indent = true;
+ settings.IndentChars = " ";
+
+ StringBuilder output = new();
+ using (XmlWriter writer = XmlWriter.Create(output, settings))
+ {
+ xml.Save(writer);
+ }
+
+ Assert.Equal("\n", output.ToString());
+ }
+ }
+}