Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
nitz opened this issue Jan 6, 2023 · 4 comments · Fixed by #81822
Labels
area-System.Xml bug help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@nitz
Copy link

nitz commented Jan 6, 2023

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.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jan 6, 2023
@ghost
Copy link

ghost commented Jan 6, 2023

Tagging subscribers to this area: @dotnet/area-system-xml
See info in area-owners.md if you want to be subscribed.

Issue Details

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

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.

Author: nitz
Assignees: -
Labels:

area-System.Xml, untriaged

Milestone: -

@krwq
Copy link
Member

krwq commented Jan 9, 2023

Hey @nitz, thanks for reporting this. Note that we're currently not actively investing in XML area (JSON is our main focus) but we're open for contributions if they're relatively low-risk. We can assist if you need any help with making contribution.

@krwq krwq added this to the Future milestone Jan 9, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 9, 2023
@krwq krwq added bug untriaged New issue has not been triaged by the area owner labels Jan 9, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 9, 2023
@krwq krwq added the help wanted [up-for-grabs] Good issue for external contributors label Jan 9, 2023
@jeffhandley
Copy link
Member

I wanted to follow up to clarify the statement above.

As @krwq said, we appreciate the issue being filed. We have moved this issue into Future as it's unlikely our team will get to this during .NET 8. We'd consider a community contribution though, and we'd be happy to review one and merge it if the risk of the change is low.

Thanks again!

@nitz
Copy link
Author

nitz commented Jan 13, 2023

Oh no worries at all; was just a really odd one that I stumbled across and was surprised to see no one else had written it down yet, so I figured that meant it was my duty :)

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Feb 8, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Feb 9, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Mar 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Xml bug help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants