2011-07-18 363 views
15

我想从网上读取一个xml文件并使用XDocument解析出来。它通常工作正常,但有时它给我这个错误的一天:'',十六进制值0x1F,是一个无效的字符。第1行,位置1

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

我试图从谷歌的一些解决方案,但他们没有对VS 2010速成的Windows Phone 7的工作

有一个解决方案它将0x1F字符替换为string.empty,但是我的代码返回一个没有替换方法的流。

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

这里是我的代码:

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

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

+1

您可以尝试发布XML内容吗? –

+0

我已经试过这个,但没有工作,仍然给出这个错误: s = s.Replace(Convert.ToString((byte)0x1F),string.Empty); Stream str = new MemoryStream(UTF8Encoding.UTF8.GetBytes(s)); –

+0

这里是我尝试阅读的xml文件: http://music.mobion.vn/api/v1/music/userstop?devid= –

回答

-1

没有人可以回答,如果你不显示相关信息 - 我指的是XML内容。

作为一般性建议,我会在ReadToEnd()调用后放置一个断点。现在你可以做几件事情:

  • 显示Xml内容到这个论坛。
  • 使用VS Xml可视化工具对其进行测试。
  • 将字符串复制粘贴到一个txt文件中并离线调查。
0

我想这可能是一个编码问题,但没有看到XML我不能肯定地说。

根据您的计划,只需替换字符但无法使用,因为您有一个流而不是文本,只需将该流读入一个字符串,然后删除不想要的字符。

16

0x1f是一个Windows控制字符。它不是有效的XML。你最好的选择是替换它。

而不是使用reader.ReadToEnd()的(其中的方式 - 一个大文件 - 最多可以使用大量的内存..但你绝对可以使用它)为什么不尝试这样的:

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

如果您愿意,您可以重新转换为流,然后按照您的要求使用。

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

否则,你可以继续做ReadToEnd的(),然后清理非法字符的字符串,并将其转换回流。

这里有一个很好的资源来清理你的xml中的非法字符 - 有可能你会有其他的...

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

3

如果您有替换的字符

对我来说,问题出现了一些问题,如果您尝试使用字符串代替字符来代替。我建议使用两者来测试一些测试值,看看它们出现了什么。另外你如何参考它有一些影响。

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

我有同样的问题,发现问题是嵌入XML一个。 的解决方案是:

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

作品与我.........

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

可能是什么情况是,内容压缩在你需要解压这种情况下它。

随着HttpHandler的,你可以做到这一点通过以下方式:

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

与“老” Web客户端,你必须派生自己的类来实现同样的效果:

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

要使用这两个你会做这样的事情:

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

这样你也收到不必.ReadToEnd(),因为你是随大流的工作,而不是利益。

相关问题