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`
}
는 입니다를 입니다.UTF8
stream
아니면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
'programing' 카테고리의 다른 글
gdb: 현재 컨텍스트에 기호 "i"가 없습니다. (0) | 2023.10.13 |
---|---|
AWS Elasticache Redis 클러스터를 Spring Boot 앱에 연결하는 방법은? (0) | 2023.10.13 |
로컬 파일을 열 수 없음 - Chrome:로컬 리소스를 로드할 수 없습니다. (0) | 2023.10.13 |
c에 더미가 없다고요? (0) | 2023.10.13 |
AngularJS: ng-model inside ng-repeat? (0) | 2023.10.13 |