103 votes

xml.LoadData - Les données au niveau de la racine ne sont pas valides. Ligne 1, position 1

J'essaie d'analyser un fichier XML dans un programme d'installation WiX. Le XML serait un objet de toutes mes erreurs retournées par un serveur web. J'obtiens l'erreur dans le titre de la question avec ce code :

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 est le suivant (comme on le voit dans la sortie de text.txt )

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

text.txt ressemble à ça :

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

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

J'ai besoin que ce XML soit analysé pour que je puisse voir si j'ai eu des erreurs.

4voto

Nenad Points 3779

Le principal responsable de cette erreur est la logique qui détermine l'encodage lors de la conversion. Stream o byte[] tableau vers .NET string .

Utilisation de StreamReader créé avec le 2ème paramètre du constructeur detectEncodingFromByteOrderMarks défini à true, déterminera l'encodage approprié et créera des string qui ne casse pas XmlDocument.LoadXml méthode.

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

L'erreur commune serait d'utiliser aveuglément UTF8 sur l'encodage stream o byte[] . Le code ci-dessous produirait string qui semble valide lorsqu'il est inspecté dans le débogueur de Visual Studio, ou copié-collé quelque part, mais qui produira l'exception lorsqu'il sera utilisé avec Load o LoadXml si le fichier est codé différemment de UTF8 sans BOM.

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

3voto

Michael Planer Points 31

J'ai résolu ce problème en éditant directement le tableau d'octets. Récupérez le préambule UTF8 et supprimez directement l'en-tête. Ensuite, vous pouvez transformer l'octet[]en une chaîne de caractères avec la méthode GetString, voir ci-dessous. Le site \r y \t Je l'ai aussi supprimé, par précaution.

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", "");

2voto

Mister Cook Points 839

Si votre xml est dans une chaîne, utilisez ce qui suit pour supprimer toute marque d'ordre des octets :

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

2voto

tibbiustin Points 51

Au début, j'ai eu des problèmes d'échappement du caractère "&", puis les diacritiques et les lettres spéciales ont été affichés comme des points d'interrogation et j'ai fini par avoir le problème mentionné par le PO.

J'ai regardé les réponses et j'ai utilisé la suggestion de @Ringo d'essayer la méthode Load() comme alternative. Cela m'a fait réaliser que je pouvais traiter ma réponse d'autres façons que sous forme de chaîne.

L'utilisation de System.IO.Stream au lieu de string a résolu tous les problèmes pour moi.

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

L'avantage de Load() est que cette méthode détecte automatiquement le format de la chaîne de caractères du XML d'entrée (par exemple, UTF-8, ANSI, etc.). Voir plus

0voto

J'ai trouvé l'une des solutions. Pour votre code, cela pourrait être comme suit -

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X