2011-07-18 106 views
15

Estoy tratando de leer un archivo xml de la web y analizarlo con XDocument. Normalmente funciona bien, pero a veces me da este error para el día:'', valor hexadecimal 0x1F, es un carácter no válido. Línea 1, posición 1

**' ', hexadecimal value 0x1F, is an invalid character. Line 1, position 1** 

He intentado algunas soluciones de Google, pero no están trabajando para VS 2010 Express Windows Phone 7.

Hay una solución que reemplaza el carácter 0x1F por string.empty pero mi código devuelve una secuencia que no tiene método de reemplazo.

s = s.Replace(Convert.ToString((byte)0x1F), string.Empty); 

Aquí está mi código:

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

archivo XML: http://music.mobion.vn/api/v1/music/userstop?devid=

+1

¿Podría intentar publicar el contenido XML también? –

+0

He intentado esto pero no funcionó, aún así me da ese error: s = s.Replace (Convert.ToString ((byte) 0x1F), string.Empty); Stream str = new MemoryStream (UTF8Encoding.UTF8.GetBytes (s)); –

+0

aquí está el archivo xml del que trato de leer: http://music.mobion.vn/api/v1/music/userstop?devid= –

Respuesta

-1

Nadie puede responder si no se presenta información relevante - me refiero al contenido XML.

Como consejo general, pondría un punto de interrupción después de la llamada a ReadToEnd(). Ahora puede hacer un par de cosas:

  • Revelar el contenido de Xml a este foro.
  • Pruébelo usando el visualizador VS Xml.
  • Copie y pegue la cadena en un archivo txt e investíguelo fuera de línea.
0

Supongo que probablemente sea un problema de codificación, pero sin ver el XML no puedo asegurarlo.

En términos de su plan para simplemente reemplazar el personaje pero no poder, porque tiene una secuencia en lugar de un texto, simplemente lea la secuencia en una cadena y luego elimine los caracteres que no desea.

16

0x1f es un personaje de control de Windows. No es XML válido. Tu mejor apuesta es reemplazarlo.

En lugar de utilizar reader.ReadToEnd() (que por cierto - para un archivo de gran tamaño - se puede utilizar una gran cantidad de memoria .. aunque sin duda se puede utilizar) por qué no intentar algo como:

string input; 
while ((input = sr.ReadLine()) != null) 
{ 
    string = string + input.Replace((char)(0x1F), ' '); 
} 

puede volver a convertir en una secuencia si lo desea, para luego utilizar como lo desee.

byte[] byteArray = Encoding.ASCII.GetBytes(input); 
MemoryStream stream = new MemoryStream(byteArray); 

O de lo contrario podría seguir haciendo ReadToEnd() y luego limpiar esa cadena de caracteres no válidos, y convertir de nuevo a un arroyo.

Aquí hay un buen recurso para limpiar caracteres ilegales en tu xml; es probable que tengas otros también ...

https://seattlesoftware.wordpress.com/tag/hexadecimal-value-0x-is-an-invalid-character/

3

Si usted está teniendo problemas reemplazando el carácter

Para mí hubo algunos problemas si intenta reemplazar el uso de la cadena en lugar del carbón. Sugiero probar algunos valores de prueba utilizando ambos para ver qué aparecen. También la forma en que lo hace referencia tiene algún efecto.

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 

I blagged this

1

que tenían el mismo problema y encontró que el problema era un  incrustado en el código XML. La solución fue:

s = s.Replace("", " ") 
0

trabaja conmigo .........

string.Replace(Chr(31), "") 
3

Qué podría estar sucediendo es que el contenido es comprimido en cuyo caso se necesita para descomprimir eso.

Con HttpHandler puede hacerlo de la siguiente manera:

var client = new HttpClient(new HttpClientHandler 
{ 
    AutomaticDecompression = DecompressionMethods.GZip 
          | DecompressionMethods.Deflate 
}); 

Con la "vieja" cliente Web que tiene que derivar su propia clase para lograr un efecto similar:

class MyWebClient : WebClient 
{ 
    protected override WebRequest GetWebRequest(Uri address) 
    { 
     HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest; 
     request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; 
     return request; 
    } 
} 

Above taken from here

Para usar los dos, haría algo como esto:

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 esta manera también reciba el beneficio de no tener que .ReadToEnd() ya se está trabajando con la corriente en su lugar.

Cuestiones relacionadas