C# 从 XmlDocument 获取带有换行符的缩进 XML 的最简单方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/203528/
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
What is the simplest way to get indented XML with line breaks from XmlDocument?
提问by Neil C. Obremski
When I build XML up from scratch with XmlDocument
, the OuterXml
property already has everything nicely indented with line breaks. However, if I call LoadXml
on some very "compressed" XML (no line breaks or indention) then the output of OuterXml
stays that way. So ...
当我从头开始构建 XML 时XmlDocument
,该OuterXml
属性已经将所有内容都很好地缩进了换行符。但是,如果我调用LoadXml
一些非常“压缩”的 XML(没有换行符或缩进),那么输出将OuterXml
保持这种状态。所以 ...
What is the simplest way to get beautified XML output from an instance of XmlDocument
?
从 的实例获得美化 XML 输出的最简单方法是XmlDocument
什么?
采纳答案by Neil C. Obremski
Based on the other answers, I looked into XmlTextWriter
and came up with the following helper method:
根据其他答案,我研究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();
}
It's a bit more code than I hoped for, but it works just peachy.
它的代码比我希望的要多一些,但它的工作原理很好。
回答by DocMax
As adapted from Erika Ehrli'sblog, this should do it:
改编自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);
}
回答by benPearce
XmlTextWriter xw = new XmlTextWriter(writer);
xw.Formatting = Formatting.Indented;
回答by Uwe Keim
If the above Beautify method is being called for an XmlDocument
that already contains an XmlProcessingInstruction
child node the following exception is thrown:
如果为XmlDocument
已经包含XmlProcessingInstruction
子节点的调用上述 Beautify 方法,则会引发以下异常:
Cannot write XML declaration. WriteStartDocument method has already written it.
无法编写 XML 声明。WriteStartDocument 方法已经写好了。
This is my modified version of the original one to get rid of the exception:
这是我为摆脱异常而修改的原始版本:
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();
}
}
It works for me now, probably you would need to scan all child nodes for the XmlProcessingInstruction
node, not just the first one?
它现在对我有用,可能您需要扫描节点的所有子XmlProcessingInstruction
节点,而不仅仅是第一个?
Update April 2015:
2015 年 4 月更新:
Since I had another case where the encoding was wrong, I searched for how to enforce UTF-8 without BOM. I found this blog postand created a function based on it:
由于我有另一个编码错误的情况,我搜索了如何在没有 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;
}
}
回答by Jonathan Mitchem
A shorter extension method version
较短的扩展方法版本
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();
}
回答by Munim Dibosh
A simple way is to use:
一个简单的方法是使用:
writer.WriteRaw(space_char);
Like this sample code, this code is what I used to create a tree view like structure using XMLWriter :
像这个示例代码一样,这个代码是我用来使用 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
这样你就可以按照你通常习惯的方式添加制表符或换行符,即 \t 或 \n
回答by JFK
Or even easier if you have access to Linq
如果您可以访问 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);
}
回答by Nyerguds
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.
在实施此处发布的建议时,我在文本编码方面遇到了问题。似乎XmlWriterSettings
忽略了 的编码,并且总是被流的编码覆盖。使用 a 时StringBuilder
,这始终是 C# 内部使用的文本编码,即 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.
重要说明:如果您的XMLDocument
对象preserveWhitespace
在加载文档时启用了其属性,则格式将被完全忽略。这让我难住了一段时间,所以请确保不要启用它。
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.
这将使用给定的文本编码将格式化的 xml 保存到磁盘。
回答by theJerm
If you have a string of XML, rather than a doc ready for use, you can do it this way:
如果您有一个 XML 字符串,而不是一个可供使用的文档,您可以这样做:
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();
}
回答by rewrew
public static string FormatXml(string xml)
{
try
{
var doc = XDocument.Parse(xml);
return doc.ToString();
}
catch (Exception)
{
return xml;
}
}