Формат XML-строки для печати дружественной XML-строки

117

У меня есть XML-строка как таковая:

<?xml version='1.0'?><response><error code='1'> Success</error></response>

Нет линий между одним элементом и другим, и поэтому их очень трудно прочитать. Я хочу функцию, которая форматирует указанную выше строку:

<?xml version='1.0'?>
<response>
<error code='1'> Success</error>
</response> 

Не прибегая к ручной записи функции формата самостоятельно, есть ли какая-либо библиотека .Net или фрагмент кода, который я могу использовать самостоятельно?

  • 1
    реквизиты для CMS, вопрос является дубликатом stackoverflow.com/questions/203528
  • 2
    Не дубликат Тот определяет XmlDocument который дисквалифицирует ответ с наибольшим количеством голосов на этот вопрос.
Теги:
formatting

9 ответов

119
Лучший ответ

Использовать XmlTextWriter...

public static String PrintXML(String XML)
{
String Result = "";

MemoryStream mStream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode);
XmlDocument document   = new XmlDocument();

try
{
    // Load the XmlDocument with the XML.
    document.LoadXml(XML);

    writer.Formatting = Formatting.Indented;

    // Write the XML into a formatting XmlTextWriter
    document.WriteContentTo(writer);
    writer.Flush();
    mStream.Flush();

    // Have to rewind the MemoryStream in order to read
    // its contents.
    mStream.Position = 0;

    // Read MemoryStream contents into a StreamReader.
    StreamReader sReader = new StreamReader(mStream);

    // Extract the text from the StreamReader.
    String FormattedXML = sReader.ReadToEnd();

    Result = FormattedXML;
}
catch (XmlException)
{
}

mStream.Close();
writer.Close();

return Result;
}
  • 6
    Это работает, если вы имеете дело с кодом, который находится на старой версии .NET Framework pre-LINQ, но другой пример намного чище.
  • 7
    Чтобы уточнить комментарий Майка: LINQ был представлен в .NET 3.5. Поэтому, если вы используете версию .NET, более раннюю, чем эта (.NET 1, 1.1, 2 или 3.0), вам придется использовать этот ответ. Но если вы используете .NET 3.5 или более позднюю версию, ответ Чарльза Пракаша Дазари будет намного проще.
Показать ещё 2 комментария
239

Вам придется разобрать контент каким-то образом... Я нахожу использование LINQ самым простым способом сделать это. Опять же, все зависит от вашего точного сценария. Вот рабочий пример с использованием LINQ для форматирования входной XML-строки.

string FormatXml(string xml)
{
     try
     {
         XDocument doc = XDocument.Parse(xml);
         return doc.ToString();
     }
     catch (Exception)
     {
         return xml;
     }
 }

[использование операторов для краткости опущено]

  • 0
    Будет ли это влиять только на разрывы строк и отступы? Я не хочу, чтобы какие-либо другие изменения, такие как «0», изменялись на «0.0» и т. Д. Когда все пустые места удаляются, я хочу, чтобы зачеркнутая строка результата была точно такой же, как и зачеркнутая строка ввода.
  • 3
    @radim Да. Никаких изменений к фактическим данным не будет. Только теги будут отформатированы и с отступом.
Показать ещё 4 комментария
37

Этот, от kristopherjohnson, лучше heaps:

  • Он также не требует заголовка документа XML.
  • Имеет более четкие исключения
  • Добавляет дополнительные параметры поведения: OmitXmlDeclaration = true, NewLineOnAttributes = true
  • Меньше строк кода

    static string PrettyXml(string xml)
    {
        var stringBuilder = new StringBuilder();
    
        var element = XElement.Parse(xml);
    
        var settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.Indent = true;
        settings.NewLineOnAttributes = true;
    
        using (var xmlWriter = XmlWriter.Create(stringBuilder, settings))
        {
            element.Save(xmlWriter);
        }
    
        return stringBuilder.ToString();
    }
    
  • 0
    Тодд, не могли бы вы уточнить, что вы подразумеваете под "не требует заголовка документа XML"? Я попробовал решение Чарльза Пракаша Дазари и просто передал фрагмент XML без объявления xml (то есть без строки <?xml version="1.0" encoding="UTF-8" ?> ), И оно работало нормально.
  • 2
    По сравнению с принятым ответом. По сравнению с Чарльзом, у этого была бы лучшая конфигурируемость. Однако я, вероятно, сам буду использовать метод Чарли в будущем, такая конфигурация будет редким требованием.
Показать ещё 1 комментарий
5

Проверьте следующую ссылку: Как довольно-печатать XML (К сожалению, ссылка теперь возвращает 404:()

Метод в ссылке принимает XML-строку в качестве аргумента и возвращает хорошо сформированную (отступы) XML-строку.

Я просто скопировал код примера из ссылки, чтобы сделать этот ответ более полным и удобным.

public static String PrettyPrint(String XML)
{
    String Result = "";

    MemoryStream MS = new MemoryStream();
    XmlTextWriter W = new XmlTextWriter(MS, Encoding.Unicode);
    XmlDocument D   = new XmlDocument();

    try
    {
        // Load the XmlDocument with the XML.
        D.LoadXml(XML);

        W.Formatting = Formatting.Indented;

        // Write the XML into a formatting XmlTextWriter
        D.WriteContentTo(W);
        W.Flush();
        MS.Flush();

        // Have to rewind the MemoryStream in order to read
        // its contents.
        MS.Position = 0;

        // Read MemoryStream contents into a StreamReader.
        StreamReader SR = new StreamReader(MS);

        // Extract the text from the StreamReader.
        String FormattedXML = SR.ReadToEnd();

        Result = FormattedXML;
    }
    catch (XmlException)
    {
    }

    MS.Close();
    W.Close();

    return Result;
}
  • 2
    Прекрасно работает для меня, я только что сделал это методом расширения строки. Кроме того, этот сайт не работает, так что хорошо, что вы зацепили копию ...
  • 1
    Дубликат ответа. @SM Kamran публикует тот же ответ тоже.
Показать ещё 3 комментария
3

Простое решение, которое работает для меня:

        XmlDocument xmlDoc = new XmlDocument();
        StringWriter sw = new StringWriter();
        xmlDoc.LoadXml(rawStringXML);
        xmlDoc.Save(sw);
        String formattedXml = sw.ToString();
  • 0
    Это не форматирует XML
  • 0
    @ Юран нет, это работает. dotnetfiddle.net/ZI98RM
1

Я пробовал:

internal static void IndentedNewWSDLString(string filePath)
{
    var xml = File.ReadAllText(filePath);
    XDocument doc = XDocument.Parse(xml);
    File.WriteAllText(filePath, doc.ToString());
}

работает нормально, как ожидалось.

  • 0
    но это удаляет тег <? xml?> вверху
1

.NET 2.0 игнорирует разрешение имен и правильное удаление ресурсов, отступы, save-whitespace и настраиваемое кодирование:

public static string Beautify(System.Xml.XmlDocument doc)
{
    string strRetValue = null;
    System.Text.Encoding enc = System.Text.Encoding.UTF8;
    // enc = new System.Text.UTF8Encoding(false);

    System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings();
    xmlWriterSettings.Encoding = enc;
    xmlWriterSettings.Indent = true;
    xmlWriterSettings.IndentChars = "    ";
    xmlWriterSettings.NewLineChars = "\r\n";
    xmlWriterSettings.NewLineHandling = System.Xml.NewLineHandling.Replace;
    //xmlWriterSettings.OmitXmlDeclaration = true;
    xmlWriterSettings.ConformanceLevel = System.Xml.ConformanceLevel.Document;


    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
    {
        using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(ms, xmlWriterSettings))
        {
            doc.Save(writer);
            writer.Flush();
            ms.Flush();

            writer.Close();
        } // End Using writer

        ms.Position = 0;
        using (System.IO.StreamReader sr = new System.IO.StreamReader(ms, enc))
        {
            // Extract the text from the StreamReader.
            strRetValue = sr.ReadToEnd();

            sr.Close();
        } // End Using sr

        ms.Close();
    } // End Using ms


    /*
    System.Text.StringBuilder sb = new System.Text.StringBuilder(); // Always yields UTF-16, no matter the set encoding
    using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(sb, settings))
    {
        doc.Save(writer);
        writer.Close();
    } // End Using writer
    strRetValue = sb.ToString();
    sb.Length = 0;
    sb = null;
    */

    xmlWriterSettings = null;
    return strRetValue;
} // End Function Beautify

Использование:

System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("C:\Test.svg");
string SVG = Beautify(xmlDoc);
0

Настраиваемый вывод Pretty XML с объявлением XML UTF-8

Следующее определение класса дает простой способ преобразования входной XML-строки в форматированный выходной XML с объявлением xml как UTF-8. Он поддерживает все параметры конфигурации, предлагаемые классом XmlWriterSettings.

using System;
using System.Text;
using System.Xml;
using System.IO;

namespace CJBS.Demo
{
    /// <summary>
    /// Supports formatting for XML in a format that is easily human-readable.
    /// </summary>
    public static class PrettyXmlFormatter
    {

        /// <summary>
        /// Generates formatted UTF-8 XML for the content in the <paramref name="doc"/>
        /// </summary>
        /// <param name="doc">XmlDocument for which content will be returned as a formatted string</param>
        /// <returns>Formatted (indented) XML string</returns>
        public static string GetPrettyXml(XmlDocument doc)
        {
            // Configure how XML is to be formatted
            XmlWriterSettings settings = new XmlWriterSettings 
            {
                Indent = true
                , IndentChars = "  "
                , NewLineChars = System.Environment.NewLine
                , NewLineHandling = NewLineHandling.Replace
                //,NewLineOnAttributes = true
                //,OmitXmlDeclaration = false
            };

            // Use wrapper class that supports UTF-8 encoding
            StringWriterWithEncoding sw = new StringWriterWithEncoding(Encoding.UTF8);

            // Output formatted XML to StringWriter
            using (XmlWriter writer = XmlWriter.Create(sw, settings))
            {
                doc.Save(writer);
            }

            // Get formatted text from writer
            return sw.ToString();
        }



        /// <summary>
        /// Wrapper class around <see cref="StringWriter"/> that supports encoding.
        /// Attribution: http://stackoverflow.com/a/427737/3063884
        /// </summary>
        private sealed class StringWriterWithEncoding : StringWriter
        {
            private readonly Encoding encoding;

            /// <summary>
            /// Creates a new <see cref="PrettyXmlFormatter"/> with the specified encoding
            /// </summary>
            /// <param name="encoding"></param>
            public StringWriterWithEncoding(Encoding encoding)
            {
                this.encoding = encoding;
            }

            /// <summary>
            /// Encoding to use when dealing with text
            /// </summary>
            public override Encoding Encoding
            {
                get { return encoding; }
            }
        }
    }
}

Возможности для дальнейшего совершенствования: -

  • Может быть создан дополнительный метод GetPrettyXml(XmlDocument doc, XmlWriterSettings settings), который позволяет вызывающему абоненту настраивать вывод.
  • Можно добавить дополнительный метод GetPrettyXml(String rawXml), который поддерживает разбор исходного текста, а не использование клиентом XmlDocument. В моем случае мне нужно было манипулировать XML с помощью XmlDocument, поэтому я не добавил этого.

Использование:

String myFormattedXml = null;
XmlDocument doc = new XmlDocument();
try
{
    doc.LoadXml(myRawXmlString);
    myFormattedXml = PrettyXmlFormatter.GetPrettyXml(doc);
}
catch(XmlException ex)
{
    // Failed to parse XML -- use original XML as formatted XML
    myFormattedXml = myRawXmlString;
}
0

если вы загружаете XMLDoc, я уверен, что функция .ToString() обладает перегрузкой для этого.

Но это для отладки? Причина, по которой он отправляется, заключается в том, чтобы заняться меньшим пространством (например, удаление лишних пробелов из XML).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню