【问题标题】:How to wrap XML under virtual root如何在虚拟根目录下包装 XML
【发布时间】:2021-11-20 12:12:18
【问题描述】:

我正在尝试加载没有根元素的 XML。我想使用 LINQ to XML。

以下回答:https://stackoverflow.com/a/18186317/16514891 我重新创建了这段代码:

var doc = File.ReadAllText(Path.Combine(Settings.GameFolderPath, path));  
var rootedDoc = "<root>" + doc + "</root>";
XDocument correctDoc = XDocument.Parse(rootedDoc);

但我在XDocument.Parse(),第 1 行,位置 9 上收到 XMLException "Unexpected XML declaration"。使用 File.WriteAllText(path, rootedDoc) 我知道第一行看起来像预期的那样:&lt;root&gt;&lt;?xml version="1.0" encoding="utf-16"?&gt;。它必须以某种方式在我链接的答案中起作用,但我不明白如何,你如何在包装原始文件后首先保持声明?

【问题讨论】:

  • 这不是一个有效的 XML 文档。 XML 声明 ?xml version="1.0" encoding="utf-16"?&gt; 必须位于文档顶部,在 &lt;root&gt; 之前
  • XML 1.0 版声明 XML 声明是可选,这意味着链接的答案并不关心 XML 文件是否包含它。但是由于您的 XML 确实包含它,它会抛出一个异常,因为如果它存在,它必须位于文档的顶部。最简单的方法可能是删除 xml.IndexOf("&lt;?")xml.IndexOf("?&gt;") 之间的所有内容
  • 好的,谢谢。所以我只是在包装之前从原始文件中删除了声明。似乎正在工作,在最坏的情况下,我可以在新文件的开头添加声明。

标签: c# linq-to-xml


【解决方案1】:

这是因为 XML 版本 1.0 指定 XML 声明(&lt;? ... ?&gt; 部分)是可选的,这意味着链接的答案可能只是忽略了它,或者只是没有使用包含它的 XML 进行测试。最简单的部分是在解析文件之前删除该 XML 声明,如下所示:

xml = xml.TrimStart("<?xml version=\"1.0\" encoding=\"utf-16\"?>");
xml = $"<root>{xml}</root>";

如果 XML 是手动创建/可以在将其传递给代码之前手动编辑,您始终可以手动删除它,尽管我不推荐它,因为这样您的程序会在摄取(否则*)有效时崩溃XML 文件。


*具有多个根元素的 XML 文件在技术上已经不是有效的 XML 文件

【讨论】:

  • 谢谢。它会起作用,但我使用的 XML 被诅咒了。当我像这样加载它时,我会遇到很多异常,因为 XML 文件本身存在错误(输入错误、重复......)。当我尝试使用自定义XMLReader 来避免XMLReader.Settings 出现一些异常时,我得到异常“没有Unicode 字节顺序标记”。我想我永远不应该尝试使用陌生人输入文件来学习编码。
  • 嗯,“无字节顺序标记”很容易修复,与 XML 无关,它指的是文件的编码,特别是它缺少所需的 byte order mark (BOM)找出文件的编码。要解决它,您可以打开文件,然后“另存为”并在“编码”下拉菜单中选择“UTF-8 BOM”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
  • 2015-05-08
相关资源
最近更新 更多