programing

xml.LoadData - 루트 수준의 데이터가 잘못되었습니다.1호선, 1번 위치

closeapi 2023. 10. 13. 22:14
반응형

xml.LoadData - 루트 수준의 데이터가 잘못되었습니다.1호선, 1번 위치

WiX 설치 프로그램 안에 있는 XML을 파싱하려고 합니다.XML은 웹 서버에서 반환된 모든 오류의 대상이 될 것입니다.다음 코드로 질문 제목에 오류가 발생합니다.

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)

<?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일 것입니다.문제에 대한 설명과 해결책은 여기서 찾을 수 있는데, 제임스 슈베르트가 여기서 발견한 제임스 브랜킨의 답변을 바탕으로 한 것입니다.

앞의 답은 숨겨진 문자를 제거하지는 않지만 첫 줄 전체도 제거합니다.더 정확한 버전은 다음과 같습니다.

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

Azure blob에서 XSLT 파일을 가져와 XslCompileed Transform 객체에 로드할 때 이 문제가 발생했습니다.제 기계에서는 파일이 멀쩡해 보였는데, 블롭으로 업로드하고 다시 불러온 후 BOM 문자가 추가되었습니다.

사용하다Load()방법 대신 문제를 해결해 줄 것입니다.더보기

여기서 문제가 된 것은myString그 헤더라인을 가지고 있었습니다.첫 번째 줄 시작 부분에 숨겨진 문자가 있었거나 줄 자체가 오류를 일으켰습니다.첫 번째 줄을 이렇게 잘라버렸습니다.

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

이것으로 문제가 해결되었습니다.

문제는 인코딩에 관한 것이라고 생각합니다.그렇기 때문에 첫 번째 줄(인코딩 바이트로)을 제거하면 문제가 해결될 수 있습니다.

루트 수준의 데이터 솔루션이 잘못되었습니다. 라인 1, 위치 1. inXDocument.Parse(xmlString)로 교체하고 있었습니다.XDocument.Load( new MemoryStream( xmlContentInBytes ) );

xml 문자열이 정상적으로 보이는 것을 확인했습니다.

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

그러나 다른 텍스트 편집기 인코딩에서는 다음과 같이 보였습니다.

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

마지막에는 xml 문자열이 필요하지 않았지만 xml byte[]가 필요했습니다.문자열을 사용해야 하는 경우 문자열에서 "보이지 않는" 바이트를 찾고 인코딩을 사용하여 구문 분석 또는 로드할 xml 내용을 조정해야 합니다.

도움이 되기를 바랍니다.

다른 인코딩으로 파일 저장:

파일 > 파일을 다음으로 저장...> 서명없이 UTF-8로 저장

VS 2017에서 Save(저장) 버튼 옆에 드롭다운으로 인코딩이 있습니다.

이 오류의 주요 원인은 변환할 때 인코딩을 결정하는 논리입니다.Stream아니면byte[] .NETstring.

으로.StreamReader두 변수 }을(를) 됩니다.detectEncodingFromByteOrderMarks하고 true합니다를 .string.XmlDocument.LoadXml방법.

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

는 입니다를 입니다.UTF8stream아니면byte[]는 합니다를 할 겁니다string 붙여넣으면 Visual Studio 디버거합니다에서 합니다.Load아니면LoadXml파일이 다르게 인코딩된 경우 BOM이 없는 UTF8.

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

저는 바이트 배열을 직접 편집하여 이 문제를 해결했습니다.UTF8 프리앰블을 수집하고 헤더를 직접 제거합니다.그런 다음 GetString 메서드를 사용하여 바이트[]를 문자열로 변환할 수 있습니다(아래 참조).내가 제거한 \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() 방법을 대안으로 시도해 보았습니다.이는 제가 단순히 끈으로만 대응하는 것이 아니라 다른 방식으로 대응할 수 있다는 것을 깨닫게 해주었습니다.

시스템을 사용합니다.IO. string이 아닌 stream이 모든 문제를 해결해 주었습니다.

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 등)을 자동으로 감지한다는 것입니다.더보기

해결책 중 하나를 알아냈습니다.코드의 경우 다음과 같을 수 있습니다.

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;
}

XmlDataDocument 개체를 사용하는 것이 XDocument 또는 XmlDocument 개체를 사용하는 것보다 훨씬 좋습니다.XmlDataDocument는 UTF8에서 잘 작동하며 Byte Order Sequences에 문제가 없습니다.ChildNode 속성을 사용하여 각 요소의 자식 노드를 가져올 수 있습니다.다음과 같은 사용자 지정 기능을 사용합니다.

        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);
                }
            }
        }
    }

XDocument를 사용하는 경우.구문 분석합니다(@"").@을 사용하면 문제가 해결됩니다.

언급URL : https://stackoverflow.com/questions/17795167/xml-loaddata-data-at-the-root-level-is-invalid-line-1-position-1

반응형