有没有人知道为什么以下代码示例因XmlException而失败“根级别的数据无效。第1行,第1位。”
var body = "<?xml version="1.0" encoding="utf-16"?><Report> ......"
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.LoadXml(body);
答案 0 :(得分:116)
虽然您的问题确实将编码设置为UTF-16,但您没有正确转义字符串,因此我不确定您是否确实将字符串准确地转换为您的问题。
我遇到了同样的例外:
System.Xml.XmlException:数据在 根级别无效。第1行, 位置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文档头中指定的编码可能不同。 E.g:
<?xml version="1.0" encoding="utf-8"?>
来自字符串here的MSDN文档:
字符串中的每个Unicode字符都是 由Unicode标量值定义, 也称为Unicode代码点或 的序数(数字)值 Unicode字符。每个代码点都是 使用UTF-16编码编码,和 每个元素的数值 编码由Char表示 对象
这意味着当您使用XML标头传递XmlDocument.LoadXml()时,必须说编码是UTF-16。否则,实际的基础编码将与标头中报告的编码不匹配,并将导致抛出XmlException。
此问题的解决方案是确保在传递Load或LoadXml方法的任何内容中使用的编码与您在XML标头中的说法相匹配。在上面的示例中,要么将XML标头更改为UTF-16状态,要么将输入编码为UTF-8并使用XmlDocument.Load methods之一。
下面是示例代码,演示如何使用MemoryStream使用定义UTF-8编码XML文档的字符串构建XmlDocument(当然,存储为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);
答案 1 :(得分:28)
简单有效的解决方案:使用LoadXml()
方法
Load()
方法
例如:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("sample.xml");
答案 2 :(得分:7)
试试这个:
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.XMLResolver = null;
bodyDoc.Load(body);
答案 3 :(得分:6)
我明白了。阅读MSDN文档,它说从字符串读取时使用.Load而不是LoadXml。发现这个工作100%的时间。奇怪的是,使用StringReader会导致问题。我认为主要原因是这是一个Unicode编码的字符串,可能会导致问题,因为StringReader只是UTF-8。
MemoryStream stream = new MemoryStream();
byte[] data = body.PayloadEncoding.GetBytes(body.Payload);
stream.Write(data, 0, data.Length);
stream.Seek(0, SeekOrigin.Begin);
XmlTextReader reader = new XmlTextReader(stream);
// MSDN reccomends we use Load instead of LoadXml when using in memory XML payloads
bodyDoc.Load(reader);
答案 4 :(得分:2)
这对我有用:
var xdoc = new XmlDocument { XmlResolver = null };
xdoc.LoadXml(xmlFragment);
答案 5 :(得分:2)
这真的挽救了我的一天。
我已经根据Zach的答案编写了一个扩展方法,我也将其扩展为使用编码作为参数,允许使用UTF-8旁边的不同编码,并将MemoryStream包装在'using'中言。
public static class XmlHelperExtentions
{
/// <summary>
/// Loads a string through .Load() instead of .LoadXml()
/// This prevents character encoding problems.
/// </summary>
/// <param name="xmlDocument"></param>
/// <param name="xmlString"></param>
public static void LoadString(this XmlDocument xmlDocument, string xmlString, Encoding encoding = null) {
if (encoding == null) {
encoding = Encoding.UTF8;
}
// Encode the XML string in a byte array
byte[] encodedString = encoding.GetBytes(xmlString);
// Put the byte array into a stream and rewind it to the beginning
using (var ms = new MemoryStream(encodedString)) {
ms.Flush();
ms.Position = 0;
// Build the XmlDocument from the MemorySteam of UTF-8 encoded bytes
xmlDocument.Load(ms);
}
}
}
答案 6 :(得分:1)
我从xml文件的绝对路径切换到相对路径时遇到了同样的问题。 以下内容解决了加载和使用相对源路径问题的问题。 使用在xaml中定义的XmlDataProvider(在代码中也应该是可能的):
<Window.Resources>
<XmlDataProvider
x:Name="myDP"
x:Key="MyData"
Source=""
XPath="/RootElement/Element"
IsAsynchronous="False"
IsInitialLoadEnabled="True"
debug:PresentationTraceSources.TraceLevel="High" /> </Window.Resources>
一旦设置了源,数据提供程序就会自动加载文档。这是代码:
m_DataProvider = this.FindResource("MyData") as XmlDataProvider;
FileInfo file = new FileInfo("MyXmlFile.xml");
m_DataProvider.Document = new XmlDocument();
m_DataProvider.Source = new Uri(file.FullName);
答案 7 :(得分:0)
简单的一行:
bodyDoc.LoadXml(new MemoryStream(Encoding.Unicode.GetBytes(body)));
答案 8 :(得分:0)
我遇到了同样的问题,因为我上传的XML文件是使用UTF-8-BOM(UTF-8字节顺序标记)编码的。
在Notepad ++中将编码切换为UTF-8,并能够在代码中加载XML文件。