我有一个XML文件,开头像这样:
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition">
<DataSources>
Run Code Online (Sandbox Code Playgroud)
当我运行以下代码时:
byte[] fileContent = //gets bytes
string stringContent = Encoding.UTF8.GetString(fileContent);
XDocument xml = XDocument.Parse(stringContent);
Run Code Online (Sandbox Code Playgroud)
我得到以下XmlException:
根级别的数据无效.第1行,第1位.
删除版本和编码节点可以解决问题.为什么?如何正确处理这个xml?
Dav*_*ray 25
我首先想到的是,当从.NET字符串类型解析XML时,编码是Unicode.看来,虽然XDocument的解析对此非常宽容.
问题实际上与UTF8前同步码/字节顺序标记(BOM)有关,它是一个三字节签名,可选地出现在UTF-8流的开头.这三个字节是关于流中使用的编码的提示.
您可以通过GetPreamble在System.Text.Encoding类的实例上调用方法来确定编码的前导码.例如:
// returns { 0xEF, 0xBB, 0xBF }
byte[] preamble = Encoding.UTF8.GetPreamble();
Run Code Online (Sandbox Code Playgroud)
前言应该正确处理XmlTextReader,所以只需加载你XDocument的XmlTextReader:
XDocument xml;
using (var xmlStream = new MemoryStream(fileContent))
using (var xmlReader = new XmlTextReader(xmlStream))
{
xml = XDocument.Load(xmlReader);
}
Run Code Online (Sandbox Code Playgroud)
ste*_*ell 17
如果您只有字节,则可以将字节加载到流中:
XmlDocument oXML;
using (MemoryStream oStream = new MemoryStream(oBytes))
{
oXML = new XmlDocument();
oXML.Load(oStream);
}
Run Code Online (Sandbox Code Playgroud)
或者您可以在加载XML之前将字节转换为字符串(假设您知道编码):
string sXml;
XmlDocument oXml;
sXml = Encoding.UTF8.GetString(oBytes);
oXml = new XmlDocument();
oXml.LoadXml(sXml);
Run Code Online (Sandbox Code Playgroud)
我已经将我的示例显示为与.NET 2.0兼容,如果您使用的是.NET 3.5,则可以使用XDocument而不是XmlDocument.
将字节加载到流中:
XDocument oXML;
using (MemoryStream oStream = new MemoryStream(oBytes))
using (XmlTextReader oReader = new XmlTextReader(oStream))
{
oXML = XDocument.Load(oReader);
}
Run Code Online (Sandbox Code Playgroud)
将字节转换为字符串:
string sXml;
XDocument oXml;
sXml = Encoding.UTF8.GetString(oBytes);
oXml = XDocument.Parse(sXml);
Run Code Online (Sandbox Code Playgroud)
为什么要打扰将文件作为字节序列读取,然后在xml文件中将其转换为字符串?只需离开框架为您加载并处理编码:
var xml = XDocument.Load("test.xml");
Run Code Online (Sandbox Code Playgroud)