C# XML序列化:如何让同级XML元素并排显示而非换行?
解决C# XML序列化时特定节点子元素同行显示的问题
默认的XmlSerializer和XmlWriter缩进配置是全局的,无法直接针对单个节点调整子元素的换行行为。要实现Address节点下的Street、HouseNo、State等子元素在同一行显示,可以通过以下两种方案解决:
方案一:自定义XmlWriter控制特定节点格式
通过继承XmlTextWriter,跟踪当前是否处于目标节点(Address)内,在写入该节点的直接子元素时跳过自动换行和缩进,改为添加空格分隔。
public class AddressInlineXmlWriter : XmlTextWriter { private bool _isInsideAddress; private int _addressDepth; public AddressInlineXmlWriter(TextWriter writer) : base(writer) { } public override void WriteStartElement(string prefix, string localName, string ns) { base.WriteStartElement(prefix, localName, ns); // 标记当前进入Address节点 if (localName.Equals("Address", StringComparison.Ordinal)) { _isInsideAddress = true; _addressDepth = Depth; } // 如果是Address的直接子元素,写入前只加空格,不换行 else if (_isInsideAddress && Depth == _addressDepth + 1) { base.WriteWhitespace(" "); } } public override void WriteEndElement() { // 如果是Address的直接子元素结束,添加空格后再闭合 if (_isInsideAddress && Depth == _addressDepth + 1) { base.WriteWhitespace(" "); } // 离开Address节点时取消标记 else if (Depth == _addressDepth) { _isInsideAddress = false; } base.WriteEndElement(); } }
使用方式:
var yourObject = new YourClass { // 初始化你的对象数据 Address = new Address { Street = "Main St", HouseNo = "123", State = "CA" } }; var serializer = new XmlSerializer(typeof(YourClass)); using (var sw = new StringWriter()) using (var writer = new AddressInlineXmlWriter(sw)) { writer.Formatting = Formatting.Indented; // 保持其他节点的缩进格式 serializer.Serialize(writer, yourObject); string formattedXml = sw.ToString(); Console.WriteLine(formattedXml); }
方案二:序列化后用XDocument调整格式
先按正常逻辑序列化XML,再通过XDocument解析并修改目标节点的子元素格式,移除空白节点并添加空格分隔子元素。
var serializer = new XmlSerializer(typeof(YourClass)); var sb = new StringBuilder(); // 第一步:正常序列化XML var settings = new XmlWriterSettings { Indent = true, IndentChars = " " }; using (var sw = new StringWriter(sb)) using (var writer = XmlWriter.Create(sw, settings)) { serializer.Serialize(writer, yourObject); } // 第二步:修改Address节点的子元素格式 var doc = XDocument.Parse(sb.ToString()); foreach (var addressNode in doc.Descendants("Address")) { // 移除Address节点内的所有空白节点 addressNode.Nodes() .Where(n => n.NodeType == XmlNodeType.Whitespace) .Remove(); // 在相邻子元素之间添加空格 var childElements = addressNode.Elements().ToList(); for (int i = 0; i < childElements.Count - 1; i++) { childElements[i].AddAfterSelf(new XText(" ")); } } // 输出调整后的XML string formattedXml = doc.ToString(); Console.WriteLine(formattedXml);
两种方案对比:
- 自定义XmlWriter方案:序列化时直接控制格式,性能更好,适合大型XML场景,但需要处理节点嵌套的边界情况。
- XDocument方案:实现更简单,逻辑直观,适合中小规模XML,无需复杂的Writer继承逻辑。
内容的提问来源于stack exchange,提问作者tira
相关产品推荐
相关产品推荐

