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

C# 格式化XML字符串以打印友好的XML字符串,c#,xml,formatting,C#,Xml,Formatting,我有这样一个XML字符串: <?xml version='1.0'?><response><error code='1'> Success</error></response> 成功 元素之间没有线条,因此很难阅读。我想要一个格式化上述字符串的函数: <?xml version='1.0'?> <response> <error code='1'> Success</error> &l

我有这样一个XML字符串:

<?xml version='1.0'?><response><error code='1'> Success</error></response>
成功
元素之间没有线条,因此很难阅读。我想要一个格式化上述字符串的函数:

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

成功

如果不亲自手动编写format函数,是否有任何.Net库或代码段可以立即使用?

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

但这是为了调试吗?这样发送的原因是占用更少的空间(即从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;
}
使用


您必须以某种方式解析内容……我发现使用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;
     }
 }
[为简洁起见,建议使用语句]

堆是否更好:

  • 它也不需要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();
    }
    

  • .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
    
    用法:

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

    internal static void IndentedNewWSDLString(string filePath)
    {
        var xml = File.ReadAllText(filePath);
        XDocument doc = XDocument.Parse(xml);
        File.WriteAllText(filePath, doc.ToString());
    }
    
    正如预期的那样,它工作正常。

    使用UTF-8 XML声明可定制的漂亮XML输出 下面的类定义提供了一种将输入XML字符串转换为格式化输出XML的简单方法,XML声明为UTF-8。它支持该类提供的所有配置选项

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

    对我有效的简单解决方案是:

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

    检查以下链接:



    作为CMS的道具,这个问题是重复的而不是重复的。这个问题指定了
    XmlDocument
    ,这将取消对这个问题投票率最高的答案的资格。这对我来说很好,我只是把它作为字符串的一个扩展方法。而且那个网站已经关闭了,所以很好你找到了一个副本…重复的答案。@s M Kamran也发布了相同的答案@瓦希德法拉赫曼迪安:是的,我没法做太多,因为我比他早一分钟发布了帖子:)顺便说一句,我想补充一下答案的来源,以给博客海报增光添彩。不幸的是,链接现在断了:(.与Charles(FormatXml)和Todd(PrettyXml)的答案相比,我最喜欢这个答案),因为这个答案没有去掉
    行。这个答案得到了我最初的想法。唯一的缺点是我更喜欢制表符,而不是本机使用的空格。我设置了
    Indentation=1
    IndentChar='\t'
    ,以获得我想要的内容。@CHICoder007感谢您对extens的评论ion方法。你教了我一些新东西。添加一个
    (这个字符串XML)
    非常有效。如果你处理的代码是旧版本的.NET framework pre-LINQ上的代码,这很有效,但是另一个例子要干净得多。为了澄清Mike的评论:LINQ是在.NET 3.5中引入的。因此,如果你使用的是旧版本的.NET framework(.NET 1、1.1、2或3.0)然后您必须使用此答案。但是如果您使用的是.NET 3.5或更高版本,Charles Prakash Dasari的答案要简单得多。@SM Kamran我正在使用您的代码,但在writer.Close()上出现的错误看起来像{“无法访问封闭流”。};请给出解决方案。@JatinGadhiya我也遇到了同样的问题,我通过使用{using block}定义流。这样,您就不需要手动关闭流,当到达using block的末尾时,流将自动关闭。Todd,您能澄清一下“不需要XML文档头”是什么意思吗?我尝试过Charles Prakash Dasari的解决方案,只是传入了一个没有XML声明的XML片段(即没有顶部的
    行)它工作得很好。与公认的答案相比。与Charles相比,这一个会有更好的可配置性。但是我自己将来可能会使用Charlies方法,这样的可配置性将是一个罕见的要求。这一个好得多,短得多。这会严格影响换行和缩进吗?我不想要任何其他更改,如“0”更改为“0.0”等等。当删除所有空白时,我希望删除的结果字符串与删除的输入字符串完全相同。@radim Yes。不会对实际数据进行任何更改。只对标记进行格式化和缩进。我注意到它在UTF8中工作良好,但在Unicode XML文件内容中不起作用。@SteveWellens,您可以访问声明via
    doc.Declaration.ToString()+doc.ToString()
    或使用
    doc.Save
    而不是
    doc.ToString
    。有关更多详细信息,请参阅。建议包括名称空间,因为这样可以避免用户在查找名称空间时查找他们以前可能不常使用的类。使用System.Xml.Linq;效果很好,谢谢!但这会删除顶部的标记。这将创建一个包含作为其标头。XmlSerializer未对此进行分析,错误为“没有Unicode字节顺序标记”。修复方法是删除encoding=“utf-16”,请参阅:。
    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;
    }
    
            XmlDocument xmlDoc = new XmlDocument();
            StringWriter sw = new StringWriter();
            xmlDoc.LoadXml(rawStringXML);
            xmlDoc.Save(sw);
            String formattedXml = sw.ToString();
    
    // Format the XML text.
    StringWriter string_writer = new StringWriter();
    XmlTextWriter xml_text_writer = new XmlTextWriter(string_writer);
    xml_text_writer.Formatting = Formatting.Indented;
    xml_document.WriteTo(xml_text_writer);
    
    // Display the result.
    txtResult.Text = string_writer.ToString();