簡體   English   中英

xml.LoadData - 根級別的數據無效。 1號線,position 1

[英]xml.LoadData - Data at the root level is invalid. Line 1, position 1

我正在嘗試在 WiX 安裝程序中解析一些 XML。 XML 將是我從 web 服務器返回的所有錯誤的 object。 我在使用此代碼的問題標題中收到錯誤:

XmlDocument xml = new XmlDocument();
try
{
    xml.LoadXml(myString);
}
catch (Exception ex)
{
    System.IO.File.WriteAllText(@"C:\text.txt", myString + "\r\n\r\n" + ex.Message);
    throw ex;
}

myString是這個(如text.txt的 output 中所見)

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

text.txt看起來像這樣:

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

Data at the root level is invalid. Line 1, position 1.

我需要這個 XML 來解析,這樣我就可以看到我是否有任何錯誤。

隱藏的字符可能是 BOM。 問題的解釋和解決方案可以在這里找到,歸功於 James Schubert,基於 James Brankin 在此處找到的答案。

盡管上一個答案確實刪除了隱藏字符,但它也刪除了整個第一行。 更精確的版本是:

string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(_byteOrderMarkUtf8))
{
    xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
}

我在從 Azure blob 獲取 XSLT 文件並將其加載到 XslCompiledTransform 對象中時遇到了這個問題。 在我的機器上,該文件看起來不錯,但在將其作為 blob 上傳並取回后,添加了 BOM 字符。

改用Load()方法,它將解決問題。 查看更多

這里的問題是myString有那個標題行。 要么在第一行的開頭有一些隱藏字符,要么是行本身導致了錯誤。 我像這樣切掉了第一行:

xml.LoadXml(myString.Substring(myString.IndexOf(Environment.NewLine)));

這解決了我的問題。

我認為問題在於編碼。 這就是為什么刪除第一行(帶有編碼字節)可能會解決問題的原因。

在根級別數據的解決方案無效。 XDocument.Parse(xmlString)第 1 行,位置 1.將其替換為XDocument.Load( new MemoryStream( xmlContentInBytes ) );

我注意到我的 xml 字符串看起來不錯:

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

但在不同的文本編輯器編碼中,它看起來像這樣:

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

最后我不需要xml字符串而是xml字節[]。 如果您需要使用字符串,您應該在字符串中查找“不可見”字節並使用編碼來調整用於解析或加載的 xml 內容。

希望它會有所幫助

使用不同的編碼保存文件:

文件 > 將文件另存為... > 另存為 UTF-8,無需簽名。

在 VS 2017 中,您可以在“保存”按鈕旁邊的下拉列表中找到編碼。

我通過直接編輯字節數組解決了這個問題。 收集 UTF8 前導碼並直接刪除標頭。 之后,您可以使用 GetString 方法將 byte[] 轉換為字符串,請參見下文。 \\r 和 \\t 我也刪除了,作為預防措施。

XmlDocument configurationXML = new XmlDocument();
List<byte> byteArray = new List<byte>(webRequest.downloadHandler.data);

foreach(byte singleByte in Encoding.UTF8.GetPreamble())
{
     byteArray.RemoveAt(byteArray.IndexOf(singleByte));
}
string xml = System.Text.Encoding.UTF8.GetString(byteArray.ToArray());
       xml = xml.Replace("\\r", "");
       xml = xml.Replace("\\t", "");

如果您的 xml 在字符串中,請使用以下內容刪除任何字節順序標記:

        xml = new Regex("\\<\\?xml.*\\?>").Replace(xml, "");

起初我在轉義“&”字符時遇到問題,然后變音符號和特殊字母顯示為問號,最終出現了 OP 提到的問題。

我查看了答案,並使用 @Ringo 的建議嘗試使用 Load() 方法作為替代方法。 這讓我意識到我可以以其他方式處理我的響應,而不僅僅是作為一個字符串。

使用 System.IO.Stream 而不是 string 為我解決了所有問題。

var response = await this.httpClient.GetAsync(url);
var responseStream = await response.Content.ReadAsStreamAsync();
var xmlDocument = new XmlDocument();
xmlDocument.Load(responseStream);

Load() 很酷的一點是,該方法會自動檢測輸入 XML 的字符串格式(例如,UTF-8、ANSI 等)。 查看更多

此錯誤的主要罪魁禍首是在將Streambyte[]數組轉換為 .NET string時確定編碼的邏輯。

使用StreamReader創建的第二個構造函數參數detectEncodingFromByteOrderMarks設置為 true,將確定正確的編碼並創建不會破壞XmlDocument.LoadXml方法的string

public string GetXmlString(string url)
{
    using var stream = GetResponseStream(url);
    using var reader = new StreamReader(stream, true);
    return reader.ReadToEnd(); // no exception on `LoadXml`
}

常見的錯誤是在streambyte[]上盲目使用UTF8編碼。 下面的代碼將生成在 Visual Studio 調試器中檢查或復制粘貼到某處時看起來有效的string ,但如果文件的編碼方式與沒有 BOM 的 UTF8 不同,則在與LoadLoadXml一起使用時會產生異常。

public string GetXmlString(string url)
{
    byte[] bytes = GetResponseByteArray(url);
    return System.Text.Encoding.UTF8.GetString(bytes); // potentially exception on `LoadXml`
}

我已經找到了解決方案之一。 對於您的代碼,這可能如下 -

XmlDocument xml = new XmlDocument();
try
{
    // assuming the location of the file is in the current directory 
    // assuming the file name be loadData.xml
    string myString = "./loadData.xml";
    xml.Load(myString);
}
catch (Exception ex)
{
    System.IO.File.WriteAllText(@"C:\text.txt", myString + "\r\n\r\n" + ex.Message);
    throw ex;
}

如果我們使用 XDocument.Parse(@"")。 使用@它可以解決問題。

使用 XmlDataDocument object 比使用 XDocument 或 XmlDocument object 好得多。XmlDataDocument 可以很好地與 UTF8 一起使用,並且它沒有字節順序序列的問題。 您可以使用 ChildNodes 屬性獲取每個元素的子節點。 使用自定義 function,如下所示:

        static public void ReadXmlDataDocument2(string xmlFilePath)
    {
        
        if (xmlFilePath != null)
        {
            if (File.Exists(xmlFilePath))
            {
                System.IO.FileStream fs = default(System.IO.FileStream);
                try
                {
                    fs = new System.IO.FileStream(xmlFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                    System.Xml.XmlDataDocument k_XDoc = new System.Xml.XmlDataDocument();
                    k_XDoc.Load(fs);
                    fs.Close();
                    fs.Dispose();
                    fs = null;

                    XmlNodeList ndsRoot = k_XDoc.ChildNodes;
                    foreach (System.Xml.XmlNode xLog in ndsRoot)
                    {
                        foreach (System.Xml.XmlNode xLog2 in xLog.ChildNodes)
                        {
                            if (xLog2.Name == "ERRORs")
                            {
                                foreach (System.Xml.XmlNode xLog3 in xLog2.ChildNodes)
                                {
                                    if (xLog3.Name == "ErrorCode")
                                    {
                                        // Do something
                                    }
                                    if (xLog3.Name == "Description")
                                    {
                                        // Do something
                                    }
                                }
                            }
                        }
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM