Background
I use Visual Studio Code most of the time for code files.
I am used to Visual Studio type of XML formatting with first attribute being in first line, rest aligned in next line with some indentation.
I have tried many extensions but it wont look exactly like in Visual Studio; either first attribute wont stay in first line or next attributes are not in alignment with first attribute first character.
I looked around for packages in NPM to achieve this , could not find anything that does the job easily. I did find couple of parsers but still you would have to recode lot of it.
Visual Studio is not open source so I dont think I will have access to the same robust code readily. So I am just trying to mock that formatting in code
TL;DR
Question 1
Is there a XML parser or formatter like Visual Studio formatter ? I could not find one , so I am just trying to mock that formatting from C#, I did read in other posts mentioning XMLWriter
with XmlWriterSettings
but I found it to be as below.
- [x] Each attribute in new line
- [ ] First attribute in first line
- [ ] Next line attributes aligned with respect to first one.
- [x] Good exception handling.
private static void FormatXML(XmlDocument xml)
{
StringBuilder sb = new StringBuilder();
var root = xml.DocumentElement;
PrintNode(root, sb);
sb.Append("\n" + "</" + root.Name + ">");
Console.WriteLine(sb.ToString());
}
private static void PrintNode(XmlNode node, StringBuilder sb)
{
sb.Append(new string(' ', firstLength) + "<" + node.Name;
if (node.Attributes?.Count > 0)
{
firstLength += new string("<" + node.Name + " ").Length;
sb.Append(" ");
for (int i = 0; i < node.Attributes.Count; i++)
{
var attribute = node.Attributes[i] as XmlAttribute;
var isLast = (i == (node.Attributes.Count - 1));
var newline = isLast ? "" : "\n";
sb.Append(attribute.Name + "=\"" + attribute.Value + "\"" + newline);
if (isLast)
sb.Append(">");
else
sb.Append(new String(' ', firstLength));
}
}
else
{
sb.Append(">");
}
//prints nodes
if (node.HasChildNodes)
{
firstLength += 2;
for (int j = 0; j < node.ChildNodes.Count; j++)
{
sb.Append("\n");
var currentSpace = firstLength;
PrintNode(node.ChildNodes[j], sb);
//close tag
if(node.ChildNodes[j].NodeType != XmlNodeType.Comment)
sb.Append("\n" + new string(' ', currentSpace) + "</" + node.ChildNodes[j].Name + ">");
}
}
return;
}
So the problem is this seems so much of manipulation and using manual string appends like <
, >
, \r\n
, xml header and spaces and so on which I dont think seems ideal. I have used ResxParser and writer in the past.
Question 2
Is it possible to extend XmlWriterSettings
/ XmlWriter
to achieve the desired formatting of XML? I dont think we have access to XmlWriter
since its in System.Xml assembly and we cant see the code unless we decompile DLL? How can I do that? If there are any open source libraries to achieve this its even better. I dont need that recommendation but the approach to improve cluttered approach of above code would be really helpful.