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

使用LINQ to XML的XDocument保存XML时自闭合标签加空格是否正常?

XDocument保存XML时自闭合标签前出现空格的问题解答

1. 这是正常行为

XML规范明确允许自闭合标签的两种写法:<genre/>和<genre />,两种格式均合法,所有标准XML解析器都能正确识别处理,不会影响XML的功能与兼容性。

2. 空格出现的原因

这是.NET中XDocument内置的XML序列化规则。早期部分旧版XML解析器对无空格的自闭合标签存在兼容性问题,微软为最大化兼容性,默认在输出自闭合标签时会在斜杠前添加一个空格。

3. 为什么SaveOptions.DisableFormatting无效

SaveOptions.DisableFormatting仅用于关闭XML的缩进、换行等格式化调整,不会改变自闭合标签的基础序列化格式。无论是否启用格式化,XDocument都会按照默认规则输出带空格的自闭合标签。

4. 如何去掉空格(若有需求)

如果业务场景要求必须使用无空格的自闭合标签,可通过以下两种方式处理:

  • 方式一:字符串替换(简单快捷)
    先将XDocument转换为字符串,再替换掉自闭合标签中的空格:

    string pathFile = Server.MapPath("\\xmlFolder\\test.xml");
    XDocument xmldoc = XDocument.Load(pathFile);
    // 转换为字符串并替换格式
    string xmlContent = xmldoc.ToString();
    xmlContent = xmlContent.Replace(" />", "/>");
    // 写入文件
    File.WriteAllText(pathFile, xmlContent, Encoding.UTF8);
    

    注意:需确保XML内容中没有其他包含" />"的文本(比如属性值),避免误替换。

  • 方式二:自定义XmlWriter(更严谨)
    继承XmlWriter并重写相关方法,自定义自闭合标签的输出格式,适合复杂场景,避免字符串替换的潜在风险:

    public class NoSpaceXmlWriter : XmlWriter
    {
        private readonly XmlWriter _innerWriter;
    
        public NoSpaceXmlWriter(XmlWriter innerWriter)
        {
            _innerWriter = innerWriter;
        }
    
        public override void WriteSelfClosingElement(string prefix, string localName, string ns)
        {
            // 自定义输出无空格的自闭合标签
            _innerWriter.WriteStartElement(prefix, localName, ns);
            _innerWriter.WriteEndElement();
        }
    
        // 其他抽象方法直接委托给_innerWriter实现
        public override void Flush() => _innerWriter.Flush();
        public override string LookupPrefix(string ns) => _innerWriter.LookupPrefix(ns);
        public override void WriteBase64(byte[] buffer, int index, int count) => _innerWriter.WriteBase64(buffer, index, count);
        public override void WriteCData(string text) => _innerWriter.WriteCData(text);
        public override void WriteCharEntity(char ch) => _innerWriter.WriteCharEntity(ch);
        public override void WriteChars(char[] buffer, int index, int count) => _innerWriter.WriteChars(buffer, index, count);
        public override void WriteComment(string text) => _innerWriter.WriteComment(text);
        public override void WriteDocType(string name, string pubid, string sysid, string subset) => _innerWriter.WriteDocType(name, pubid, sysid, subset);
        public override void WriteEndAttribute() => _innerWriter.WriteEndAttribute();
        public override void WriteEndDocument() => _innerWriter.WriteEndDocument();
        public override void WriteEndElement() => _innerWriter.WriteEndElement();
        public override void WriteEntityRef(string name) => _innerWriter.WriteEntityRef(name);
        public override void WriteFullEndElement() => _innerWriter.WriteFullEndElement();
        public override void WriteProcessingInstruction(string name, string text) => _innerWriter.WriteProcessingInstruction(name, text);
        public override void WriteRaw(string data) => _innerWriter.WriteRaw(data);
        public override void WriteRaw(char[] buffer, int index, int count) => _innerWriter.WriteRaw(buffer, index, count);
        public override void WriteStartAttribute(string prefix, string localName, string ns) => _innerWriter.WriteStartAttribute(prefix, localName, ns);
        public override void WriteStartDocument(bool standalone) => _innerWriter.WriteStartDocument(standalone);
        public override void WriteStartDocument() => _innerWriter.WriteStartDocument();
        public override void WriteStartElement(string prefix, string localName, string ns) => _innerWriter.WriteStartElement(prefix, localName, ns);
        public override void WriteString(string text) => _innerWriter.WriteString(text);
        public override void WriteSurrogateCharEntity(char lowChar, char highChar) => _innerWriter.WriteSurrogateCharEntity(lowChar, highChar);
        public override void WriteWhitespace(string ws) => _innerWriter.WriteWhitespace(ws);
        public override XmlWriterSettings Settings => _innerWriter.Settings;
        public override WriteState WriteState => _innerWriter.WriteState;
        public override void Close() => _innerWriter.Close();
    }
    

    使用示例:

    string pathFile = Server.MapPath("\\xmlFolder\\test.xml");
    XDocument xmldoc = XDocument.Load(pathFile);
    XmlWriterSettings settings = new XmlWriterSettings
    {
        Indent = true,
        Encoding = Encoding.UTF8
    };
    using (var innerWriter = XmlWriter.Create(pathFile, settings))
    using (var writer = new NoSpaceXmlWriter(innerWriter))
    {
        xmldoc.WriteTo(writer);
    }
    

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:01:02