c# - 为什么包含 XML header 时 C# XmlDocument.LoadXml(string) 会失败?

标签 c# .net xml

有没有人知道为什么以下代码示例失败并出现 XmlException“根级别的数据无效。第 1 行,位置 1。”

var body = "<?xml version="1.0" encoding="utf-16"?><Report> ......"
XmlDocument bodyDoc = new XmlDocument();            
bodyDoc.LoadXml(body);

最佳答案

背景

虽然您的问题确实将编码设置为 UTF-16,但您没有正确转义字符串,所以我不确定您是否确实将字符串准确地转置为您的问题。

我遇到了同样的异常:

System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.

但是,我的代码是这样的:

string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);

问题

问题是字符串在 .NET 中内部存储为 UTF-16,但 XML 文档 header 中指定的编码可能不同。例如:

<?xml version="1.0" encoding="utf-8"?>

来自字符串的 MSDN 文档 here :

Each Unicode character in a string is defined by a Unicode scalar value, also called a Unicode code point or the ordinal (numeric) value of the Unicode character. Each code point is encoded using UTF-16 encoding, and the numeric value of each element of the encoding is represented by a Char object.

这意味着当您将带有 XML header 的字符串传递给 XmlDocument.LoadXml() 时,它必须说明编码是 UTF-16。否则,实际的底层编码将与 header 中报告的编码不匹配,并将导致抛出 XmlException。

解决方案

此问题的解决方案是确保无论您传递给 Load 还是 LoadXml 方法,使用的编码都与您在 XML header 中所说的相匹配。在我上面的示例中,要么将您的 XML header 更改为声明 UTF-16,要么将输入编码为 UTF-8 并使用 XmlDocument.Load methods 之一。 .

下面的示例代码演示了如何使用 MemoryStream 来构建 XmlDocument,该 XmlDocument 使用定义 UTF-8 编码 XML 文档的字符串(当然,存储的是 UTF-16 .NET 字符串)。

string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";

// Encode the XML string in a UTF-8 byte array
byte[] encodedString = Encoding.UTF8.GetBytes(xml);

// Put the byte array into a stream and rewind it to the beginning
MemoryStream ms = new MemoryStream(encodedString);
ms.Flush();
ms.Position = 0;

// Build the XmlDocument from the MemorySteam of UTF-8 encoded bytes
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ms);

关于c# - 为什么包含 XML header 时 C# XmlDocument.LoadXml(string) 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/310669/

相关文章:

c# - 正则表达式,提取编号列表(多行)

c# - 如果为 null,则实例化一个变量

来自 StringIO 源的 Python xml etree DTD?

c# - 使用 .NET 将原始数据打印到热敏打印机

c# - TextBlock 中的上标或下标

.net - .NET 中的 Plupload - 在 Plupload 控件中引发错误

java - 在 MyBatis 中列出 'IN' 子句

xml - 删除不需要的 xml 节点

c# - Windows 窗体 : using BackgroundImage slows down drawing of the Form's controls

c# - asp.net http 处理程序和动态 css 生成