programing

XML 문자열을 인쇄할 형식 지정 XML 문자열

javajsp 2023. 10. 1. 19:17

XML 문자열을 인쇄할 형식 지정 XML 문자열

다음과 같은 XML 문자열이 있습니다.

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

한 요소와 다른 요소 사이에는 선이 없으므로 읽기가 매우 어렵습니다.위 문자열을 포맷하는 함수를 원합니다.

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

포맷 기능을 직접 수동으로 작성하는 것이 아니라, 방법이 없을까요?바로 사용할 수 있는 넷 라이브러리 또는 코드 스니펫?

내용을 어떻게든 파싱해야 합니다...저는 LINQ를 사용하는 것이 가장 쉬운 방법이라고 생각합니다.다시 말하지만, 이 모든 것은 당신의 정확한 시나리오에 달려있습니다.다음은 입력 XML 문자열을 포맷하기 위해 LINQ를 사용하는 작업 예입니다.

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

[간단히 설명하기 위해 문장 사용 생략]

사용...

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

크리스토퍼 존슨이 쓴 이 은 훨씬 더 낫습니다.

  1. XML 문서 헤더도 필요 없습니다.
  2. 더 명확한 예외가 있음
  3. 추가 동작 옵션을 추가합니다.OmitXmlDeclaration = true, NewLineOn 특성 = 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();
    }
    

저에게 효과적인 간단한 솔루션:

        XmlDocument xmlDoc = new XmlDocument();
        StringWriter sw = new StringWriter();
        xmlDoc.LoadXml(rawStringXML);
        xmlDoc.Save(sw);
        String formattedXml = sw.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;
}

노력했습니다.

internal static void IndentedNewWSDLString(string filePath)
{
    var xml = File.ReadAllText(filePath);
    XDocument doc = XDocument.Parse(xml);
    File.WriteAllText(filePath, doc.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);

를 사용하여 스트리밍 변환을 통해 XML 문자열을 미리 인쇄할 수 있습니다.이방법

독자에서 작성자로 모든 것을 복사하고 다음 형제의 시작으로 독자를 옮깁니다.

다음 확장 메서드를 정의합니다.

public static class XmlExtensions
{
    public static string FormatXml(this string xml, bool indent = true, bool newLineOnAttributes = false, string indentChars = "  ", ConformanceLevel conformanceLevel = ConformanceLevel.Document) => 
        xml.FormatXml( new XmlWriterSettings { Indent = indent, NewLineOnAttributes = newLineOnAttributes, IndentChars = indentChars, ConformanceLevel = conformanceLevel });

    public static string FormatXml(this string xml, XmlWriterSettings settings)
    {
        using (var textReader = new StringReader(xml))
        using (var xmlReader = XmlReader.Create(textReader, new XmlReaderSettings { ConformanceLevel = settings.ConformanceLevel } ))
        using (var textWriter = new StringWriter())
        {
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                xmlWriter.WriteNode(xmlReader, true);
            return textWriter.ToString();
        }
    }
}

이제 다음을 수행할 수 있습니다.

var inXml = @"<?xml version='1.0'?><response><error code='1'> Success</error></response>";
var newXml = inXml.FormatXml(indentChars : "", newLineOnAttributes : false); // Or true, if you prefer
Console.WriteLine(newXml);

인쇄하는 것

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

주의:

  • 다른 답변은 XML을 다음과 같은 일부 문서 객체 모델에 로드합니다.XmlDocument아니면XDocument/XElement, 그런 다음 들여쓰기를 활성화한 상태에서 DOM을 다시 직렬화합니다.

    이 스트리밍 솔루션은 DOM의 추가 메모리 오버헤드를 완전히 방지합니다.

  • 질문에서 중첩에 대한 들여쓰기를 추가하지 않습니다.<error code='1'> Success</error>노드, 그래서 설정했습니다.indentChars : "". 일반적으로 한 수준당 두 개의 공백을 들여쓰기하는 것이 일반적입니다.

  • 속성 구분 기호는 현재 단일 따옴표인 경우 무조건 이중 따옴표로 변환됩니다.(다른 답변들도 마찬가지라고 생각합니다.)

  • conformanceLevel : ConformanceLevel.Fragment에서는 XML 조각의 시퀀스를 포함하는 문자열을 포맷할 수 있습니다.

  • .ConformanceLevel.Fragment XML 에 한 형식이어야 합니다.면,XmlReader예외를 던집니다.

데모 피들이 여기 있습니다.

UTF-8 XML 선언으로 사용자 지정 가능한 Pretty XML 출력

다음 클래스 정의는 입력 XML 문자열을 UTF-8로 선언하는 형식의 출력 XML로 변환하는 간단한 방법을 제공합니다.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를 사용하도록 하는 대신 원시 텍스트 구문 분석을 지원하는 추가할 수 있습니다.저의 경우 XmlDocument를 사용하여 XML을 조작해야 했기 때문에 이것을 추가하지 않았습니다.

용도:

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

다음 링크를 확인합니다.C#에서 보기 좋게 XML 파일 형식 지정

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

XMLDoc을 로드해 주신다면, 저는 그것을.ToString() 함수는 이에 대한 오버로드를 허용합니다.

하지만 이것은 디버깅을 위한 것입니까?이렇게 전송되는 이유는 공간을 적게 차지하기 위해서입니다(즉, XML에서 불필요한 공백을 제거하기 위해서입니다).

안녕하세요, 그냥 이걸 시도해보시는게 어때요?

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = false;
....
....
xmlDoc.Save(fileName);

Whitespace = false를 보존합니다. 이 옵션은 xml beautifier도 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/1123718/format-xml-string-to-print-friendly-xml-string