1

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.

Morse
  • 8,258
  • 7
  • 39
  • 64
  • What stopping you from implementing your own XmlWriter that write elements the way you want? It's just dozen pretty straightforward methods... – Alexei Levenkov Mar 28 '20 at 00:23
  • @AlexeiLevenkov Thats what the code I have posted here is doing by the way, but its not subclassing `XmlWriter` – Morse Mar 28 '20 at 01:36
  • 1
    The code in the post obviously producing invalid XML and likely does not handle all PI/Comments/CDATA sections correctly... Implementing XmlWriter is somewhat easier way to support all cases and do it correctly... But I'm somewhat confused what you are actually trying to get out of this question - you are not asking for recommendation (which would make question off-topic) and already have code that satisfies your needs (even if code is not technically correct)… And you don't seem to want to implement XmlWriter which would be natural way of doing it... – Alexei Levenkov Mar 28 '20 at 01:54
  • ... with enough answer on SO like https://stackoverflow.com/questions/32149676/custom-xmlwriter-to-skip-a-certain-element. – Alexei Levenkov Mar 28 '20 at 01:56
  • @AlexeiLevenkov ok.thank you. you are leading me to the correct path.I've removed comment handling code here,and this works for valid XML. I am trying to ask better of doing as this doesnt handle all cases and I dont understand when you say implement XmlWriter , do I have to subclass it and override methods? – Morse Mar 28 '20 at 03:12
  • The code in the can't produce valid XML as there is no traces of encoding (like "A & B > C" value can't be just written as is) - this may be fine for data you have. Yes XmlWriter (as you likely seen already) is abstract class that is designed to be derived from to implement individual methods writing particular elements... – Alexei Levenkov Mar 28 '20 at 03:18
  • Got it. Thanks again! – Morse Mar 28 '20 at 03:24

0 Answers0