[英]Parsing xml string to an xml document fails if the string begins with <?xml… ?> section
我有一個像這樣開頭的 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>
當我運行以下代碼時:
byte[] fileContent = //gets bytes
string stringContent = Encoding.UTF8.GetString(fileContent);
XDocument xml = XDocument.Parse(stringContent);
我得到以下 XmlException:
根級別的數據無效。 第 1 行,位置 1。
刪除版本和編碼節點可以解決問題。 為什么? 如何正確處理這個xml?
我的第一個想法是從 .NET 字符串類型解析 XML 時編碼是 Unicode。 看起來,盡管 XDocument 的解析對此相當寬容。
該問題實際上與 UTF8 前導碼/字節順序標記 (BOM) 相關,它是一個三字節的簽名,可選擇出現在 UTF-8 流的開頭。 這三個字節是有關流中使用的編碼的提示。
您可以通過對System.Text.Encoding
類的實例調用GetPreamble
方法來確定編碼的前導碼。 例如:
// returns { 0xEF, 0xBB, 0xBF }
byte[] preamble = Encoding.UTF8.GetPreamble();
XmlTextReader
應該正確處理序言,因此只需從XmlTextReader
加載您的XDocument
:
XDocument xml;
using (var xmlStream = new MemoryStream(fileContent))
using (var xmlReader = new XmlTextReader(xmlStream))
{
xml = XDocument.Load(xmlReader);
}
如果您只有字節,則可以將字節加載到流中:
XmlDocument oXML;
using (MemoryStream oStream = new MemoryStream(oBytes))
{
oXML = new XmlDocument();
oXML.Load(oStream);
}
或者您可以在加載 XML 之前將字節轉換為字符串(假設您知道編碼):
string sXml;
XmlDocument oXml;
sXml = Encoding.UTF8.GetString(oBytes);
oXml = new XmlDocument();
oXml.LoadXml(sXml);
我已將我的示例顯示為與 .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);
}
將字節轉換為字符串:
string sXml;
XDocument oXml;
sXml = Encoding.UTF8.GetString(oBytes);
oXml = XDocument.Parse(sXml);
您的 XML 開頭是否有字節順序標記(BOM),它是否與您的編碼匹配? 如果你砍掉你的標題,你也會砍掉 BOM,如果這是不正確的,那么后續的解析可能會起作用。
您可能需要在字節級別檢查您的文檔以查看 BOM。
為什么要費心將文件作為字節序列讀取,然后在它是 xml 文件時將其轉換為字符串? 只需讓框架為您加載並處理編碼:
var xml = XDocument.Load("test.xml");
嘗試這個:
int startIndex = xmlString.IndexOf('<');
if (startIndex > 0)
{
xmlString = xmlString.Remove(0, startIndex);
}
我也遇到過這個錯誤,因為源 XML 是一個字符串,它以某種方式獲得了一些似乎破壞XmlDocument
或XDocument
解析的不可打印字符。 剝離它們解決了這個問題:
string sanitized = Regex.Replace(part, @"\p{C}+", string.Empty);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.