You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:50:20