Кто-нибудь знает, почему в следующем примере кода возникает ошибка XmlException «Данные на корневом уровне недействительны. Строка 1, позиция 1.»
var body = "<?xml version = "1.0" encoding = "utf-16"?><Report> ......"
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.LoadXml(body);
Вы уверены, что в теле установлена кодировка utf-16, а не что-то другое? Кроме того, действительно ли ваша строка тела экранирована, например body = "<? xml version = \" 1.0 \ "encoding = \" utf-16 \ "?> \ n <Report> Это тест </Report>";





Я понял. Прочтите документацию MSDN, в которой говорится, что при чтении из строк следует использовать .Load вместо LoadXml. Выяснилось, что это работает в 100% случаев. Как ни странно, использование StringReader вызывает проблемы. Я думаю, что основная причина в том, что это строка в кодировке Unicode, и это может вызвать проблемы, потому что StringReader поддерживает только UTF-8.
MemoryStream stream = new MemoryStream();
byte[] data = body.PayloadEncoding.GetBytes(body.Payload);
stream.Write(data, 0, data.Length);
stream.Seek(0, SeekOrigin.Begin);
XmlTextReader reader = new XmlTextReader(stream);
// MSDN reccomends we use Load instead of LoadXml when using in memory XML payloads
bodyDoc.Load(reader);
Чтение документации MSDN для XmlDocument.LoadXml (String) здесь: msdn.microsoft.com/en-us/library/… сводка метода гласит: «Загружает XML-документ из указанной строки». Однако, как вы заявили, в нем говорится: «Если вы хотите загрузить из Stream, String, TextReader или XmlReader, используйте метод Load вместо этого метода». Кроме того, если вы посмотрите на XmlDocument.Load (String), он говорит: URL-адрес файла, содержащего XML-документ для загрузки. «URL-адрес может быть либо локальным файлом, либо URL-адресом HTTP (веб-адресом)». (больше в другом комментарии)
Я считаю, что предполагаемая цель строки «Если вы хотите загрузить из Stream, String, ...» на самом деле «Если вы хотите загрузить из Stream, File, ...», но у них есть String, потому что загрузка из Файл принимает строковый параметр в качестве имени файла. Я не верю, что их намерение состоит в том, «если вы хотите загрузить XmlDocument из строки в памяти, используйте Load». В конце концов, это заявленная цель LoadXml (String)! Хотя ваше решение обеспечивает обходной путь, я не думаю, что оно решает актуальную заявленную проблему (которая у меня тоже есть) с помощью XmlDocument.LoadXml (String).
Хотя ваш вопрос имеет кодировку, установленную как UTF-16, у вас нет строки, должным образом экранированной, поэтому я не был уверен, действительно ли вы точно перенесли строку в свой вопрос.
Я столкнулся с тем же исключением:
System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
Однако мой код выглядел так:
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
Проблема в том, что строки хранятся внутри как UTF-16 в .NET, однако кодировка, указанная в заголовке XML-документа, может быть другой. Например.:
<?xml version = "1.0" encoding = "utf-8"?>
Из документации MSDN для String здесь:
Each Unicode character in a string is defined by a Unicode scalar value, also called a Unicode code point or the ordinal (numeric) value of the Unicode character. Each code point is encoded using UTF-16 encoding, and the numeric value of each element of the encoding is represented by a Char object.
Это означает, что когда вы передаете XmlDocument.LoadXml () свою строку с заголовком XML, она должна указывать кодировку UTF-16. В противном случае фактическая базовая кодировка не будет соответствовать кодировке, указанной в заголовке, и приведет к возникновению исключения XmlException.
Решение этой проблемы состоит в том, чтобы убедиться, что кодировка, используемая во всем, что вы передаете методу Load или LoadXml, соответствует тому, что вы говорите в заголовке XML. В моем примере выше либо измените заголовок XML на состояние UTF-16, либо закодируйте ввод в UTF-8 и используйте один из Методы XmlDocument.Load.
Ниже приведен пример кода, демонстрирующий, как использовать MemoryStream для создания XmlDocument с использованием строки, которая определяет XML-документ в кодировке UTF-8 (но, конечно, хранится строка UTF-16 .NET).
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<event>This is a Test</event>";
// Encode the XML string in a UTF-8 byte array
byte[] encodedString = Encoding.UTF8.GetBytes(xml);
// Put the byte array into a stream and rewind it to the beginning
MemoryStream ms = new MemoryStream(encodedString);
ms.Flush();
ms.Position = 0;
// Build the XmlDocument from the MemorySteam of UTF-8 encoded bytes
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ms);
не забывайте ms.close ()
Или используя оператор MemoryStream
Попробуй это:
XmlDocument bodyDoc = new XmlDocument();
bodyDoc.XMLResolver = null;
bodyDoc.Load(body);
Это сработало для меня:
var xdoc = new XmlDocument { XmlResolver = null };
xdoc.LoadXml(xmlFragment);
Простое и эффективное решение: вместо использования метода LoadXml() используйте метод Load().
Например:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("sample.xml");
это было намного легче сделать и понять. В моем документе не было заголовков xml.
Это действительно спасло мне день.
Я написал метод расширения, основанный на ответе Зака, также я расширил его, чтобы использовать кодировку в качестве параметра, позволяя использовать различные кодировки помимо UTF-8, и я заключил MemoryStream в оператор using.
public static class XmlHelperExtentions
{
/// <summary>
/// Loads a string through .Load() instead of .LoadXml()
/// This prevents character encoding problems.
/// </summary>
/// <param name = "xmlDocument"></param>
/// <param name = "xmlString"></param>
public static void LoadString(this XmlDocument xmlDocument, string xmlString, Encoding encoding = null) {
if (encoding == null) {
encoding = Encoding.UTF8;
}
// Encode the XML string in a byte array
byte[] encodedString = encoding.GetBytes(xmlString);
// Put the byte array into a stream and rewind it to the beginning
using (var ms = new MemoryStream(encodedString)) {
ms.Flush();
ms.Position = 0;
// Build the XmlDocument from the MemorySteam of UTF-8 encoded bytes
xmlDocument.Load(ms);
}
}
}
У меня была такая же проблема при переключении с абсолютного на относительный путь для моего файла xml. Следующее решает проблемы как с загрузкой, так и с использованием относительного исходного пути. Использование XmlDataProvider, который определен в xaml (также должно быть возможно в коде):
<Window.Resources>
<XmlDataProvider
x:Name = "myDP"
x:Key = "MyData"
Source = ""
XPath = "/RootElement/Element"
IsAsynchronous = "False"
IsInitialLoadEnabled = "True"
debug:PresentationTraceSources.TraceLevel = "High" /> </Window.Resources>
Поставщик данных автоматически загружает документ после установки источника. Вот код:
m_DataProvider = this.FindResource("MyData") as XmlDataProvider;
FileInfo file = new FileInfo("MyXmlFile.xml");
m_DataProvider.Document = new XmlDocument();
m_DataProvider.Source = new Uri(file.FullName);
Простая строка:
bodyDoc.LoadXml(new MemoryStream(Encoding.Unicode.GetBytes(body)));
У меня была такая же проблема, потому что загружаемый мной XML-файл был закодирован с использованием UTF-8-BOM (знак байтового порядка UTF-8).
Переключил кодировку на UTF-8 в Notepad ++ и смог загрузить XML-файл в коде.
Дэн прав - код в порядке. Один быстрый и простой способ проверить xml - открыть его в Internet Explorer.