Skip to content

XmlWellFormedWriter ignores XmlWriterSettings.NewLineOnAttributes for attributes specifically named xmlns #80306

@nitz

Description

@nitz

Description

When writing an XDocument to a stream via XmlWriter, even if specifically requested, attributes specifically named xmlns will not write on their own line. Other attributes don't suffer this issue.

Reproduction Steps

See this .NET Fiddle: https://dotnetfiddle.net/PCyVdc (.NET 7)
(Similar fiddle for .NET Framework 4.7.2 here.)

Code from fiddle reproduced here.
using System;
using System.Xml;
using System.Xml.Linq;
using System.IO;
					
public class Program
{
	public static void Main()
	{
		XmlWriterSettings writerSettings = new() {
			// enable newlines on attributes
			NewLineOnAttributes = true,
			
			// value of NewLineHandling doesn't chnage behavior
			//NewLineHandling = NewLineHandling.None,
			//NewLineHandling = NewLineHandling.Entitize,
			NewLineHandling = NewLineHandling.Replace,
			
			// value of NewLineChars doesn't change behavior
			NewLineChars = "\n",
			
			// if Indent is false, no newlines will be written at all,
			// regardless of NewLineHandling; which seems improper 🤷🏻‍♀️
			Indent = true,
		};
		
		string[] tests = new[] {
			// this test will properly writes each attribute on their own lines
			"""<?xml version="1.0" encoding="utf-8"?><data attrib1="1" attrib2="2" attrib3="3" attrib4="4"><child /></data>""",
			// xmlns is written next to the element name, but other attributes are correctly written on their own line
			"""<?xml version="1.0" encoding="utf-8"?><data xmlns="1" attrib2="2" attrib3="3" attrib4="4"><child /></data>""",
			// no newline after attrib3, xmlns is written on the same line
			"""<?xml version="1.0" encoding="utf-8"?><data attrib1="1" attrib2="2" attrib3="3" xmlns="4"><child /></data>""",
			// no newline after attrib2, xmlns is written on the same line, but attrib4 is correctly written on it's own line
			"""<?xml version="1.0" encoding="utf-8"?><data attrib1="1" attrib2="2" xmlns="3" attrib4="4"><child /></data>""",
			// the same as above, just on an empty element
			"""<?xml version="1.0" encoding="utf-8"?><data attrib1="1" attrib2="2" xmlns="3" attrib4="4" />""",
		};
		
		foreach (string test in tests)
		{
			FormatAndPrint(test, writerSettings);
		}
	}
	
	public static void FormatAndPrint(string s, XmlWriterSettings writerSettings)
	{
		// load the xml string, and write it to memory
		XDocument xd = XDocument.Parse(s);
		using MemoryStream stream = new();
		using XmlWriter writer = XmlWriter.Create(stream, writerSettings);
		xd.WriteTo(writer);
		writer.Flush();

		// read the written xml back out out of memory, and write it to console
		stream.Position = 0;
		using StreamReader reader = new StreamReader(stream, writerSettings.Encoding);
		string xml = reader.ReadToEnd();
		Console.WriteLine("---");
		Console.WriteLine(xml);
		Console.WriteLine();
	}
}

Expected behavior

All written attributes should be on their own lines when XmlWriterSettings.NewLineOnAttributes is true.

Actual behavior

Attributes specifically named xmlns are always written on the same line the writer is currently on, regardless of XmlWriterSettings member values.

Regression?

Unlikely. I was able to reproduce it against the following runtimes: .NET 7, .NET 6, .NET 5, .NET Core 3.1, .NET Framework 4.7.2

Known Workarounds

Manually write the XML, or post-process the writer's output and manually insert a newline & indentation.

Configuration

Example code is running against .NET 7.

OS/Arch unlikely to change outcome.

Other information

None yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions