XmlDocument에서 줄 바꿈을 사용하여 들여 쓰기 된 XML을 얻는 가장 간단한 방법은 무엇입니까?
나는 처음부터 XML을 구축 할 때 XmlDocument
의 OuterXml
속성은 이미 잘 줄 바꿈과 들여 모든 것을 갖추고 있습니다. 그러나 LoadXml
매우 "압축 된"XML (줄 바꿈이나 들여 쓰기 없음)을 호출 하면 출력이 OuterXml
그대로 유지됩니다. 그래서 ...
의 인스턴스에서 아름다운 XML 출력을 얻는 가장 간단한 방법은 무엇입니까 XmlDocument
?
다른 답변을 바탕으로 XmlTextWriter
다음 도우미 방법을 조사 하고 생각해 냈습니다.
static public string Beautify(this XmlDocument doc)
{
StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace
};
using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
doc.Save(writer);
}
return sb.ToString();
}
내가 기대했던 것보다 약간 더 많은 코드지만, 그냥 복숭아처럼 작동합니다.
Erika Ehrli의 블로그 에서 채택한대로 다음 과 같이해야합니다.
XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
// Save the document to a file and auto-indent the output.
using (XmlTextWriter writer = new XmlTextWriter("data.xml", null)) {
writer.Formatting = Formatting.Indented;
doc.Save(writer);
}
Linq에 액세스 할 수 있으면 더 쉽습니다.
try
{
RequestPane.Text = System.Xml.Linq.XElement.Parse(RequestPane.Text).ToString();
}
catch (System.Xml.XmlException xex)
{
displayException("Problem with formating text in Request Pane: ", xex);
}
더 짧은 확장 메서드 버전
public static string ToIndentedString( this XmlDocument doc )
{
var stringWriter = new StringWriter(new StringBuilder());
var xmlTextWriter = new XmlTextWriter(stringWriter) {Formatting = Formatting.Indented};
doc.Save( xmlTextWriter );
return stringWriter.ToString();
}
XmlDocument
이미 XmlProcessingInstruction
자식 노드가 포함 된에 대해 위의 Beautify 메서드가 호출 되면 다음 예외가 발생합니다.
XML 선언을 작성할 수 없습니다. WriteStartDocument 메서드가 이미 작성했습니다.
이것은 예외를 제거하기 위해 원래 버전의 수정 된 버전입니다.
private static string beautify(
XmlDocument doc)
{
var sb = new StringBuilder();
var settings =
new XmlWriterSettings
{
Indent = true,
IndentChars = @" ",
NewLineChars = Environment.NewLine,
NewLineHandling = NewLineHandling.Replace,
};
using (var writer = XmlWriter.Create(sb, settings))
{
if (doc.ChildNodes[0] is XmlProcessingInstruction)
{
doc.RemoveChild(doc.ChildNodes[0]);
}
doc.Save(writer);
return sb.ToString();
}
}
이제 저에게 효과적입니다 XmlProcessingInstruction
. 첫 번째 노드뿐만 아니라 모든 하위 노드에서 노드를 검색해야 할까요?
2015 년 4 월 업데이트 :
인코딩이 잘못된 또 다른 경우가 있었기 때문에 BOM없이 UTF-8을 적용하는 방법을 찾았습니다. 이 블로그 게시물을 발견 하고이를 기반으로 함수를 만들었습니다.
private static string beautify(string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = "\t",
NewLineChars = Environment.NewLine,
NewLineHandling = NewLineHandling.Replace,
Encoding = new UTF8Encoding(false)
};
using (var ms = new MemoryStream())
using (var writer = XmlWriter.Create(ms, settings))
{
doc.Save(writer);
var xmlString = Encoding.UTF8.GetString(ms.ToArray());
return xmlString;
}
}
XmlTextWriter xw = new XmlTextWriter(writer);
xw.Formatting = Formatting.Indented;
public static string FormatXml(string xml)
{
try
{
var doc = XDocument.Parse(xml);
return doc.ToString();
}
catch (Exception)
{
return xml;
}
}
간단한 방법은 다음을 사용하는 것입니다.
writer.WriteRaw(space_char);
이 샘플 코드와 마찬가지로이 코드는 XMLWriter를 사용하여 구조와 같은 트리 뷰를 만드는 데 사용한 것입니다.
private void generateXML(string filename)
{
using (XmlWriter writer = XmlWriter.Create(filename))
{
writer.WriteStartDocument();
//new line
writer.WriteRaw("\n");
writer.WriteStartElement("treeitems");
//new line
writer.WriteRaw("\n");
foreach (RootItem root in roots)
{
//indent
writer.WriteRaw("\t");
writer.WriteStartElement("treeitem");
writer.WriteAttributeString("name", root.name);
writer.WriteAttributeString("uri", root.uri);
writer.WriteAttributeString("fontsize", root.fontsize);
writer.WriteAttributeString("icon", root.icon);
if (root.children.Count != 0)
{
foreach (ChildItem child in children)
{
//indent
writer.WriteRaw("\t");
writer.WriteStartElement("treeitem");
writer.WriteAttributeString("name", child.name);
writer.WriteAttributeString("uri", child.uri);
writer.WriteAttributeString("fontsize", child.fontsize);
writer.WriteAttributeString("icon", child.icon);
writer.WriteEndElement();
//new line
writer.WriteRaw("\n");
}
}
writer.WriteEndElement();
//new line
writer.WriteRaw("\n");
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
This way you can add tab or line breaks in the way you are normally used to, i.e. \t or \n
When implementing the suggestions posted here, I had trouble with the text encoding. It seems the encoding of the XmlWriterSettings
is ignored, and always overridden by the encoding of the stream. When using a StringBuilder
, this is always the text encoding used internally in C#, namely UTF-16.
So here's a version which supports other encodings as well.
IMPORTANT NOTE: The formatting is completely ignored if your XMLDocument
object has its preserveWhitespace
property enabled when loading the document. This had me stumped for a while, so make sure not to enable that.
My final code:
public static void SaveFormattedXml(XmlDocument doc, String outputPath, Encoding encoding)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\t";
settings.NewLineChars = "\r\n";
settings.NewLineHandling = NewLineHandling.Replace;
using (MemoryStream memstream = new MemoryStream())
using (StreamWriter sr = new StreamWriter(memstream, encoding))
using (XmlWriter writer = XmlWriter.Create(sr, settings))
using (FileStream fileWriter = new FileStream(outputPath, FileMode.Create))
{
if (doc.ChildNodes.Count > 0 && doc.ChildNodes[0] is XmlProcessingInstruction)
doc.RemoveChild(doc.ChildNodes[0]);
// save xml to XmlWriter made on encoding-specified text writer
doc.Save(writer);
// Flush the streams (not sure if this is really needed for pure mem operations)
writer.Flush();
// Write the underlying stream of the XmlWriter to file.
fileWriter.Write(memstream.GetBuffer(), 0, (Int32)memstream.Length);
}
}
This will save the formatted xml to disk, with the given text encoding.
If you have a string of XML, rather than a doc ready for use, you can do it this way:
var xmlString = "<xml>...</xml>"; // Your original XML string that needs indenting.
xmlString = this.PrettifyXml(xmlString);
private string PrettifyXml(string xmlString)
{
var prettyXmlString = new StringBuilder();
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
var xmlSettings = new XmlWriterSettings()
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace
};
using (XmlWriter writer = XmlWriter.Create(prettyXmlString, xmlSettings))
{
xmlDoc.Save(writer);
}
return prettyXmlString.ToString();
}
A more simplified approach based on the accepted answer:
static public string Beautify(this XmlDocument doc) {
StringBuilder sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true
};
using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
doc.Save(writer);
}
return sb.ToString();
}
Setting the new line is not necessary. Indent characters also has the default two spaces so I preferred not to set it as well.
'program tip' 카테고리의 다른 글
Python의 로깅 기능에 사용자 지정 로그 수준을 추가하는 방법 (0) | 2020.08.17 |
---|---|
보기 위해 프로세스 출력에 첨부 (0) | 2020.08.17 |
C ++ / Linux에서 디렉토리 트리를 어떻게 만들 수 있습니까? (0) | 2020.08.17 |
스위치 문과 함께 열거 형을 사용하는 Java (0) | 2020.08.16 |
PDO를 사용하여 NULL 값을 어떻게 삽입합니까? (0) | 2020.08.16 |