使用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
相关产品推荐
相关产品推荐

