C# 格式化 XML 字符串以打印友好的 XML 字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1123718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:45:33  来源:igfitidea点击:

Format XML String to Print Friendly XML String

c#xmlformatting

提问by Graviton

I have an XML string as such:

我有一个这样的 XML 字符串:

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

There are no lines between one element and another, and thus is very difficult to read. I want a function that formats the above string:

一个元素和另一个元素之间没有线,因此很难阅读。我想要一个格式化上述字符串的函数:

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

Without resorting to manually write the format function myself, is there any .Net library or code snippet that I can use offhand?

无需自己手动编写格式函数,是否有任何我可以随意使用的 .Net 库或代码片段?

采纳答案by S M Kamran

Use XmlTextWriter...

使用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)
    {
        // Handle the exception
    }

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

    return result;
}

回答by Spence

if you load up the XMLDoc I'm pretty sure the .ToString() function posses an overload for this.

如果您加载 XMLDoc,我很确定 .ToString() 函数为此具有重载。

But is this for debugging? The reason that it is sent like that is to take up less space (i.e stripping unneccessary whitespace from the XML).

但这是为了调试吗?像这样发送它的原因是占用更少的空间(即从 XML 中去除不必要的空白)。

回答by Chansik Im

Check the following link: How to pretty-print XML(Unfortunately, the link now returns 404 :()

检查以下链接:如何漂亮地打印 XML(不幸的是,该链接现在返回 404 :()

The method in the link takes an XML string as an argument and returns a well-formed (indented) XML string.

链接中的方法将 XML 字符串作为参数,并返回格式正确(缩进)的 XML 字符串。

I just copied the sample code from the link to make this answer more comprehensive and convenient.

我只是从链接中复制了示例代码,以使这个答案更加全面和方便。

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;
}

回答by Charles Prakash Dasari

You will have to parse the content somehow ... I find using LINQ the most easy way to do it. Again, it all depends on your exact scenario. Here's a working example using LINQ to format an input XML string.

您将不得不以某种方式解析内容……我发现使用 LINQ 是最简单的方法。同样,这完全取决于您的具体情况。这是一个使用 LINQ 格式化输入 XML 字符串的工作示例。

string FormatXml(string xml)
{
     try
     {
         XDocument doc = XDocument.Parse(xml);
         return doc.ToString();
     }
     catch (Exception)
     {
         // Handle and throw if fatal exception here; don't just ignore them
         return xml;
     }
 }

[using statements are ommitted for brevity]

[为简洁起见省略了 using 语句]

回答by Todd

This one, from kristopherjohnsonis heaps better:

这个来自 kristopherjohnson的效果更好:

  1. It doesn't require an XML document header either.
  2. Has clearer exceptions
  3. Adds extra behaviour options: OmitXmlDeclaration = true, NewLineOnAttributes = true
  4. Less lines of code

    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();
    }
    
  1. 它也不需要 XML 文档标题。
  2. 有更明确的例外
  3. 添加额外的行为选项:OmitXmlDeclaration = true,NewLineOnAttributes = true
  4. 更少的代码行

    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();
    }
    

回答by Stefan Steiger

.NET 2.0 ignoring name resolving, and with proper resource-disposal, indentation, preserve-whitespace and custom encoding:

.NET 2.0 忽略名称解析,并具有适当的资源处理、缩进、保留空白和自定义编码

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

Usage:

用法:

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

回答by Akhilesh singh

I tried:

我试过:

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

it is working fine as expected.

它按预期工作正常。

回答by CJBS

Customizable Pretty XML output with UTF-8 XML declaration

带有 UTF-8 XML 声明的可定制的漂亮的 XML 输出

The following class definition gives a simple method to convert an input XML string into formatted output XML with the xml declaration as UTF-8. It supports all the configuration options that the XmlWriterSettingsclass offers.

以下类定义提供了一种简单的方法,将输入 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; }
            }
        }
    }
}

Possibilities for further improvement:-

进一步改进的可能性:-

  • An additional method GetPrettyXml(XmlDocument doc, XmlWriterSettings settings)could be created that allows the caller to customize the output.
  • An additional method GetPrettyXml(String rawXml)could be added that supports parsing raw text, rather than have the client use the XmlDocument. In my case, I needed to manipulate the XML using the XmlDocument, hence I didn't add this.
  • GetPrettyXml(XmlDocument doc, XmlWriterSettings settings)可以创建一个额外的方法,允许调用者自定义输出。
  • GetPrettyXml(String rawXml)可以添加支持解析原始文本的附加方法,而不是让客户端使用 XmlDocument。就我而言,我需要使用 XmlDocument 操作 XML,因此我没有添加它。

Usage:

用法:

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;
}

回答by ZeeProgrammer

The simple solution that is working for me:

对我有用的简单解决方案:

        XmlDocument xmlDoc = new XmlDocument();
        StringWriter sw = new StringWriter();
        xmlDoc.LoadXml(rawStringXML);
        xmlDoc.Save(sw);
        String formattedXml = sw.ToString();