Visual Studio, как форматирование XML из синтаксического анализа C # Xml

Фон

Я использую Visual Studio Code большую часть времени для файлов кода.

Я привык к форматированию XML в Visual Studio, где первый атрибут находится в первой строке, остальные выровнены в следующей строке с некоторым отступом.

Я пробовал много расширений, но они не будут выглядеть точно так же, как в Visual Studio; либо первый атрибут не останется в первой строке, либо следующие атрибуты не совпадают с первым символом первого атрибута.

Я искал пакеты в NPM, чтобы добиться этого, но не смог найти ничего, что бы легко выполняло эту работу. Я нашел пару парсеров, но вам все равно пришлось бы многое перекодировать.

Visual Studio не имеет открытого исходного кода, поэтому я не думаю, что у меня будет доступ к такому же надежному коду. Поэтому я просто пытаюсь издеваться над этим форматированием в коде.

TL;DR

Вопрос 1

Существует ли синтаксический анализатор или средство форматирования XML, например средство форматирования Visual Studio? Я не смог найти его, поэтому я просто пытаюсь издеваться над этим форматированием из C #, я читал в других сообщениях, где упоминается XMLWriter с XmlWriterSettings, но я обнаружил, что это выглядит так, как показано ниже.

  • [x] Каждый атрибут в новой строке
  • [ ] Первый атрибут в первой строке
  • [ ] Атрибуты следующей строки выровнены по отношению к первой.
  • [x] Хорошая обработка исключений.
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;
}

Таким образом, проблема в том, что это кажется таким большим количеством манипуляций и использования ручных добавлений строк, таких как <, >, \r\n , заголовок xml и пробелы и так далее, что я не думаю, кажется идеальным. Раньше я использовал ResxParser и Writer.

вопрос 2

Можно ли расширить XmlWriterSettings/XmlWriter для достижения желаемого форматирования XML? Я не думаю, что у нас есть доступ к XmlWriter, поскольку он находится в сборке System.Xml, и мы не можем увидеть код, если не декомпилируем DLL? Как я могу это сделать? Если есть какие-либо библиотеки с открытым исходным кодом для достижения этой цели, это даже лучше. Мне не нужна эта рекомендация, но подход к улучшению загроможденного подхода вышеприведенного кода был бы действительно полезен.


person Morse    schedule 27.03.2020    source источник
comment
Что мешает вам реализовать собственный XmlWriter, который записывает элементы так, как вы хотите? Это всего лишь дюжина довольно простых методов...   -  person Alexei Levenkov    schedule 28.03.2020
comment
@AlexeiLevenkov Вот что делает код, который я разместил здесь, кстати, но он не является подклассом XmlWriter   -  person Morse    schedule 28.03.2020
comment
Код в сообщении явно создает недопустимый XML и, вероятно, неправильно обрабатывает все разделы PI/Comments/CDATA... Реализация XmlWriter - несколько более простой способ поддерживать все случаи и делать это правильно... Но я несколько смущен тем, что вы на самом деле пытаетесь уйти от этого вопроса - вы не просите рекомендации (что сделало бы вопрос не по теме) и уже имеете код, который удовлетворяет ваши потребности (даже если код технически неверен) ... И вы, кажется, не хотите реализовать XmlWriter, что было бы естественным способом сделать это...   -  person Alexei Levenkov    schedule 28.03.2020
comment
... с достаточным ответом на SO, например stackoverflow.com/questions/32149676/.   -  person Alexei Levenkov    schedule 28.03.2020
comment
@AlexeiLevenkov хорошо.спасибо. вы ведете меня по правильному пути. Я удалил здесь код обработки комментариев, и это работает для действительного XML. Я пытаюсь попросить лучше сделать, так как это не обрабатывает все случаи, и я не понимаю, когда вы говорите реализовать XmlWriter , нужно ли мне создавать подклассы и переопределять методы?   -  person Morse    schedule 28.03.2020
comment
Код в файле не может создать действительный XML, так как нет следов кодирования (например, значение A & B > C не может быть просто записано как есть) — это может подойти для имеющихся у вас данных. Да, XmlWriter (как вы, вероятно, уже видели) — это абстрактный класс, который предназначен для реализации отдельных методов, записывающих определенные элементы...   -  person Alexei Levenkov    schedule 28.03.2020
comment
Понятно. Спасибо еще раз!   -  person Morse    schedule 28.03.2020