J'essaie de lire un fichier XML sur le Web et de l'analyser à l'aide de XDocument. Cela fonctionne normalement mais parfois cela me donne cette erreur pour la journée:
**' ', hexadecimal value 0x1F, is an invalid character. Line 1, position 1**
J'ai essayé certaines solutions de Google, mais elles ne fonctionnent pas pour VS 2010 Express Windows Phone 7.
Il existe une solution qui remplace le caractère 0x1F par string.empty mais mon code retourne un flux qui n'a pas de méthode replace.
s = s.Replace(Convert.ToString((byte)0x1F), string.Empty);
Voici mon code:
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (var reader = new StreamReader(e.Result))
{
int[] counter = { 1 };
string s = reader.ReadToEnd();
Stream str = e.Result;
// s = s.Replace(Convert.ToString((byte)0x1F), string.Empty);
// byte[] str = Convert.FromBase64String(s);
// Stream memStream = new MemoryStream(str);
str.Position = 0;
XDocument xdoc = XDocument.Load(str);
var data = from query in xdoc.Descendants("user")
select new mobion
{
index = counter[0]++,
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
listBox.ItemsSource = data;
}
}
Fichier XML: http://music.mobion.vn/api/v1/music/userstop?devid=
Envisagez d'utiliser System.Web.HttpUtility.HtmlDecode si vous décodez du contenu lu sur le Web.
0x1f est un caractère de contrôle Windows. Ce n'est pas XML valide. Votre meilleur pari est de le remplacer.
Au lieu d'utiliser reader.ReadToEnd () (qui, en passant - pour un fichier volumineux - peut utiliser beaucoup de mémoire .. bien que vous puissiez vraiment l'utiliser), pourquoi ne pas essayer quelque chose comme:
string input;
while ((input = sr.ReadLine()) != null)
{
string = string + input.Replace((char)(0x1F), ' ');
}
vous pouvez reconvertir un flux si vous le souhaitez, puis l'utiliser à votre guise.
byte[] byteArray = Encoding.ASCII.GetBytes( input );
MemoryStream stream = new MemoryStream( byteArray );
Sinon, vous pouvez continuer à lire readToEnd (), puis nettoyer cette chaîne de caractères non autorisés et les reconvertir en flux.
Voici une bonne ressource pour nettoyer les caractères illégaux dans votre xml - il y a de fortes chances que vous en ayez d'autres aussi ...
https://seattlesoftware.wordpress.com/tag/hexadecimal-value-0x-is-an-invalid-character/
Si vous rencontrez des problèmes pour remplacer le caractère
Pour moi, il y avait quelques problèmes si vous essayez de remplacer en utilisant la chaîne au lieu du caractère. Je suggère d'essayer certaines valeurs de test en utilisant les deux pour voir ce qu'elles apparaissent. Aussi comment vous référencez cela a un effet.
var a = x.IndexOf('\u001f'); // 513
var b = x.IndexOf(Convert.ToString((byte)0x1F)); // -1
x = x.Replace(Convert.ToChar((byte)0x1F), ' '); // Works
x = x.Replace(Convert.ToString((byte)0x1F), " "); // Fails
Ce qui pourrait arriver est que le contenu est compressé, auquel cas vous devez le décompresser.
Avec HttpHandler, vous pouvez le faire de la manière suivante:
var client = new HttpClient(new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip
| DecompressionMethods.Deflate
});
Avec le "vieux" Web Client, vous devez créer votre propre classe pour obtenir le même effet:
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
Pour utiliser les deux, vous feriez quelque chose comme ceci:
HttpClient
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
{
using (var stream = client.GetStreamAsync(url))
{
using (var sr = new StreamReader(stream.Result))
{
using (var reader = XmlReader.Create(sr))
{
var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(reader);
foreach (var item in feed.Items)
{
Console.WriteLine(item.Title.Text);
}
}
}
}
}
WebClient
using (var stream = new MyWebClient().OpenRead("http://myrss.url"))
{
using (var sr = new StreamReader(stream))
{
using (var reader = XmlReader.Create(sr))
{
var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(reader);
foreach (var item in feed.Items)
{
Console.WriteLine(item.Title.Text);
}
}
}
}
De cette façon, vous bénéficiez également de l'avantage de ne pas avoir à .ReadToEnd () puisque vous utilisez plutôt le flux.
J'ai eu le même problème et j'ai constaté qu'il s'agissait d'un 
intégré au fichier XML .
s = s.Replace("", " ")
J'imagine que c'est probablement un problème d'encodage, mais sans voir le code XML, je ne peux pas le dire avec certitude.
En ce qui concerne votre plan pour remplacer simplement le caractère mais ne pas pouvoir le faire, car vous avez un flux plutôt qu'un texte, lisez simplement le flux dans une chaîne, puis supprimez les caractères que vous ne souhaitez pas.
Travaille pour moi.........
string.Replace(Chr(31), "")
J'ai utilisé XmlSerializer pour analyser le code XML et je suis confronté à la même exception ... Le problème est que la chaîne XML contient des codes HTML contenant des caractères non valides.
Cette méthode supprime tous les codes HTML non valides de la chaîne (en fonction de ce fil - https://forums.asp.net/t/1483793.aspx?Need+a+method+that+removes+illegal+XML+characters+from + a + String ):
public static string RemoveInvalidXmlSubstrs(string xmlStr)
{
string pattern = "&#((\\d+)|(x\\S+));";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(xmlStr))
{
xmlStr = regex.Replace(xmlStr, new MatchEvaluator(m =>
{
string s = m.Value;
string unicodeNumStr = s.Substring(2, s.Length - 3);
int unicodeNum = unicodeNumStr.StartsWith("x") ?
Convert.ToInt32(unicodeNumStr.Substring(1), 16)
: Convert.ToInt32(unicodeNumStr);
//according to https://www.w3.org/TR/xml/#charsets
if ((unicodeNum == 0x9 || unicodeNum == 0xA || unicodeNum == 0xD) ||
((unicodeNum >= 0x20) && (unicodeNum <= 0xD7FF)) ||
((unicodeNum >= 0xE000) && (unicodeNum <= 0xFFFD)) ||
((unicodeNum >= 0x10000) && (unicodeNum <= 0x10FFFF)))
{
return s;
}
else
{
return String.Empty;
}
})
);
}
return xmlStr;
}