如何为无根元素的XML添加虚拟根节点以适配LINQ to XML解析
问题原因
XML 规范明确要求 XML 声明 <?xml ...?> 必须位于整个文档的最开头位置,不能嵌套在任何元素内部。你当前的拼接逻辑把 <root> 放在了 XML 声明前面,导致声明出现在根节点内部,不符合语法要求,所以触发异常。你参考的原方案能正常运行,是因为对应的场景里原始 XML 内容本身没有 XML 声明,直接包裹根节点不会出现语法冲突。
解决方案
方案1:保留原XML声明,调整拼接顺序
先从读取到的原始XML内容中提取XML声明,再把声明放在拼接后的文档最前面,再放置包裹了<root>的内容:
var rawXml = File.ReadAllText(Path.Combine(Settings.GameFolderPath, path)); string xmlDeclaration = string.Empty; // 检查是否存在XML声明 if (rawXml.TrimStart().StartsWith("<?xml")) { // 定位声明结束位置 int declarationEndIndex = rawXml.IndexOf("?>") + 2; xmlDeclaration = rawXml.Substring(0, declarationEndIndex); rawXml = rawXml.Substring(declarationEndIndex); } // 按规范顺序拼接 var rootedDoc = $"{xmlDeclaration}<root>{rawXml}</root>"; XDocument correctDoc = XDocument.Parse(rootedDoc);
方案2:移除原XML声明,自定义声明
如果不需要保留原始XML的声明配置,可以直接去掉原声明后再包裹根节点,也可以按需手动给XDocument添加声明:
var rawXml = File.ReadAllText(Path.Combine(Settings.GameFolderPath, path)); // 移除原XML声明 if (rawXml.TrimStart().StartsWith("<?xml")) { int declarationEndIndex = rawXml.IndexOf("?>") + 2; rawXml = rawXml.Substring(declarationEndIndex); } var rootedDoc = $"<root>{rawXml}</root>"; XDocument correctDoc = XDocument.Parse(rootedDoc); // 可选:手动添加自定义XML声明 correctDoc.Declaration = new XDeclaration("1.0", "utf-16", null);
内容的提问来源于stack exchange,提问作者Helios21cz
相关产品推荐
相关产品推荐

