XDocument 在一行中写入特定的 XElement
Posted
技术标签:
【中文标题】XDocument 在一行中写入特定的 XElement【英文标题】:XDocument write specific XElement in a single line 【发布时间】:2019-07-31 09:41:23 【问题描述】:我正在使用XDocument
编写一个 XML 文件。我想调整文件布局。让我解释一下,这里是生成文件的摘录:
<ROOTELEMENT>
<CHILDELEMENT>
<INFO1>Test a 1</INFO1>
<INFO2>Test a 2</INFO2>
</CHILDELEMENT>
<CHILDELEMENT>
<INFO1>Test b 1</INFO1>
<INFO2>Test b 2</INFO2>
</CHILDELEMENT>
<ROOTELEMENT>
我希望我的文件看起来像这样:
<ROOTELEMENT>
<CHILDELEMENT><INFO1>Test a 1</INFO1><INFO2>Test a 2</INFO2></CHILDELEMENT>
<CHILDELEMENT><INFO1>Test b 1</INFO1><INFO2>Test b 2</INFO2></CHILDELEMENT>
</ROOTELEMENT>
这是我的代码:
var myDoc = new XDocument(new XElement("ROOTELEMENT",
new XElement("CHILDELEMENT",
new XElement("INFO1", "Test a 1"),
new XElement("INFO2", "Test a 2")),
new XElement("CHILDELEMENT",
new XElement("INFO1", "Test b 1"),
new XElement("INFO2", "Test b 2"))));
myDoc.Save("Test.xml");
【问题讨论】:
真的很重要吗?看起来主要是格式问题 是的,这是格式问题。我正在替换用另一种语言编写的另一个应用程序,并且我希望输出与我的新应用程序出现之前完全相同。 我的意思是,XML 的缩进并不重要。任何半途而废的 XML 解析器都会忽略它,我什至不确定是否有一些东西没有 对我的客户来说,确实如此。我猜是为了节省内存并保持文件可读。 How do you create an indented XML string from an XDocument in c#?的可能重复 【参考方案1】:XML 输出的格式由XmlWriter
而非XElement
或XDocument
控制,因此如果您需要精确控制格式,则需要通过继承XmlWriter
的实现之一来创建自己的编写器,特别是XmlTextWriter
的 Formatting
属性是可变的,可以在写入期间更改。
例如,这是一个在元素深度超过 1 时禁用缩进的版本:
public class CustomFormattingXmlTextWriter : XmlTextWriter
readonly Stack<Formatting> stack = new Stack<Formatting>();
public CustomFormattingXmlTextWriter(TextWriter writer, int indentDepth) : base(writer)
this.Formatting = Formatting.Indented;
this.IndentDepth = indentDepth;
int IndentDepth get;
void OnElementStarted(string localName, string ns)
stack.Push(Formatting);
// You could e.g. modify the logic here to check to see whether localName == CHILDELEMENT
// if (localName == "CHILDELEMENT")
if (stack.Count == IndentDepth+1)
Formatting = Formatting.None;
void OnElementEnded()
var old = stack.Pop();
if (old != Formatting)
Formatting = old;
public override void WriteStartElement(string prefix, string localName, string ns)
base.WriteStartElement(prefix, localName, ns);
OnElementStarted(localName, ns);
public override void WriteEndElement()
base.WriteEndElement();
OnElementEnded();
public override void WriteFullEndElement()
base.WriteEndElement();
OnElementEnded();
public static partial class XNodeExtensions
public static void SaveWithCustomFormatting(this XDocument doc, string filename, int indentDepth)
using (var textWriter = new StreamWriter(filename))
using (var writer = new CustomFormattingXmlTextWriter(textWriter, indentDepth))
doc.Save(writer);
使用它,你可以做到:
myDoc.SaveWithCustomFormatting(fileName, 1);
根据需要输出:
<ROOTELEMENT>
<CHILDELEMENT><INFO1>Test a 1</INFO1><INFO2>Test a 2</INFO2></CHILDELEMENT>
<CHILDELEMENT><INFO1>Test b 1</INFO1><INFO2>Test b 2</INFO2></CHILDELEMENT>
</ROOTELEMENT>
注意事项:
您可以修改CustomFormattingXmlTextWriter.OnElementStarted()
中的逻辑,以使用您希望的任何标准禁用格式化,例如检查传入的localName
是否为CHILDELEMENT
。
XmlTextWriter
被XmlWriter
弃用——但后者没有可变的Formatting
属性。如果您必须使用XmlWriter
,您可以查看Is there a way to serialize multiple XElements onto the same line?。
演示小提琴 #1 here.
【讨论】:
以上是关于XDocument 在一行中写入特定的 XElement的主要内容,如果未能解决你的问题,请参考以下文章