source

XDocument에서 Xml을 문자열로 가져오는 방법은 무엇입니까?

factcode 2023. 9. 21. 21:33
반응형

XDocument에서 Xml을 문자열로 가져오는 방법은 무엇입니까?

저는 XML에 LINQ를 처음 사용합니다. 당신이 구축한 후에XDocument, 당신은 어떻게 그것을 얻습니까?OuterXml당신이 그랬던 것처럼XmlDocument?

개체의 재정의된 ToString() 메서드만 사용하면 됩니다.

XDocument xmlDoc ...
string xml = xmlDoc.ToString();

XElement 등 모든 XO 개체에서 작동합니다.

언제 바뀌었는지는 모르겠지만 오늘(2017년 7월) 정답을 시험해보니

"시스템.Xml.Xml 문서"

대신에ToString(), 당신은 원래 의도된 방법을 사용할 수 있습니다.XmlDocument내용: 스트림에 xml 문서 쓰기.

XmlDocument xml = ...;
string result;

using (StringWriter writer = new StringWriter())
{
  xml.Save(writer);
  result = writer.ToString();
}

몇 개의 답변이 약간 틀린 답변을 제공합니다.

  • XDocument.ToString()XML 선언을 생략합니다(그리고 @Alex Gordon에 따르면 다음과 같이 인코딩된 특이한 문자를 포함하는 경우 잘못된 XML을 반환할 수 있습니다).&).
  • 저장XDocument로.StringWriter야기할 것입니다.배출할 NETencoding="utf-16", 아마 원하지 않을 것입니다(XML을 문자열로 저장한다면 나중에 파일로 저장하고 싶어서일 것이며, 파일을 저장하기 위한 사실상의 표준은 UTF-8 -입니다.NET은 달리 명시되지 않는 한 텍스트 파일을 UTF-8로 저장합니다.
  • @울프강 그린펠드의 대답은 옳은 방향으로 가고 있지만 불필요하게 복잡합니다.

다음을 사용합니다.

  var memory = new MemoryStream();
  xDocument.Save(memory);
  string xmlText = Encoding.UTF8.GetString(memory.ToArray());

이렇게 하면 UTF-8 선언이 포함된 XML 텍스트가 반환됩니다.

X Document.ToString()은 전체 XML을 얻을 수 없습니다.

XML 문서 시작 부분의 XML 선언을 문자열로 가져오려면 XDocument를 사용합니다.저장() 메서드:

    var ms = new MemoryStream();
    using (var xw = XmlWriter.Create(new StreamWriter(ms, Encoding.GetEncoding("ISO-8859-1"))))
        new XDocument(new XElement("Root", new XElement("Leaf", "data"))).Save(xw);
    var myXml = Encoding.GetEncoding("ISO-8859-1").GetString(ms.ToArray());

ToString()을 사용하여 XDocument를 문자열로 변환합니다.

string result = string.Empty;
XElement root = new XElement("xml",
    new XElement("MsgType", "<![CDATA[" + "text" + "]]>"),
    new XElement("Content", "<![CDATA[" + "Hi, this is Wilson Wu Testing for you! You can ask any question but no answer can be replied...." + "]]>"),
    new XElement("FuncFlag", 0)
);
result = root.ToString();

@wolfgang-grinfeld의 대답은 기술적으로 정확하지만 (이것은 단지 사용하는 것이 아니라 XML 선언을 생성하기 때문에).ToString()method), 코드는 어떤 이유로 UTF-8 바이트 순서 표시(BOM)를 생성했습니다.XDocument.Parse(string)메서드가 처리할 수 없으며 던집니다.Data at the root level is invalid. Line 1, position 1.오류를 범실.

다음은 BOM이 없는 또 다른 솔루션입니다.

var utf8Encoding =
    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

using (var memory = new MemoryStream())
using (var writer = XmlWriter.Create(memory, new XmlWriterSettings
       {
           OmitXmlDeclaration = false,
           Encoding = utf8Encoding
       }))
{
    CompanyDataXml.Save(writer);
    writer.Flush();
    return utf8Encoding.GetString(memory.ToArray());
}

이 답변들을 보면 XML 선언을 자동으로 생성하는 과정에서 불필요한 복잡성과 비효율이 많이 보입니다.하지만 선언문이 너무 단순하기 때문에 그것을 만들어내는 데 큰 가치가 없습니다.그냥 KISS(간단하게 해, 바보야):

// Extension method
public static string ToStringWithDeclaration(this XDocument doc, string declaration = null)
{
    declaration ??= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
    return declaration + doc.ToString();
}

// Usage
string xmlString = doc.ToStringWithDeclaration();
// Or
string xmlString = doc.ToStringWithDeclaration("...");

사용.XmlWriter대신에ToString()출력의 형식을 더 잘 제어할 수 있습니다(예: 들여쓰기를 원하는 경우). 그리고 다른 대상에 쓸 수 있습니다.string.

메모리 스트림을 대상으로 하는 이유는 성능 때문입니다.다에 수 .string을 알고 에,에)string는 항상 C#)의 UTF-16입니다.예를 들어 HTTP 요청의 경우:

// Extension method
public static ByteArrayContent ToByteArrayContent(
    this XDocument doc, XmlWriterSettings xmlWriterSettings = null)
{
    xmlWriterSettings ??= new XmlWriterSettings();
    using (var stream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(stream, xmlWriterSettings))
        {
            doc.Save(writer);
        }
        var content = new ByteArrayContent(stream.GetBuffer(), 0, (int)stream.Length);
        content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
        return content;
    }
}

// Usage (XDocument -> UTF-8 bytes)
var content = doc.ToByteArrayContent();
var response = await httpClient.PostAsync("/someurl", content);

// Alternative (XDocument -> string -> UTF-8 bytes)
var content = new StringContent(doc.ToStringWithDeclaration(), Encoding.UTF8, "text/xml");
var response = await httpClient.PostAsync("/someurl", content);

저는 마이크로소프트에서 이 예시를 발견했습니다.XDocument용 NET 6 설명서.저장방법.원래 질문(XmlDocument의 XDocument equivalent는 무엇인가?)에 대한 답을 주는 것 같습니다.OuterXml), 그리고 다른 사람들이 이미 지적한 우려에 대해서도 설명합니다.XmlWritingSettings를 사용하면 문자열 출력을 예측 가능하게 제어할 수 있습니다.

https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument.save

StringBuilder sb = new StringBuilder();
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
 
using (XmlWriter xw = XmlWriter.Create(sb, xws)) {
    XDocument doc = new XDocument(
        new XElement("Child",
            new XElement("GrandChild", "some content")
        )
    );
    doc.Save(xw);
}
Console.WriteLine(sb.ToString());

언급URL : https://stackoverflow.com/questions/4533609/how-to-get-xml-as-string-from-xdocument

반응형