“ ”,十六进制值为0x1F,是一个无效字符。第1行,第1个位置。

20

我正在尝试从Web读取一个XML文件,并使用XDocument解析它。通常它能正常工作,但有时会出现以下错误:

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

我在Google上尝试了一些解决方案,但它们都不能用于VS 2010 Express Windows Phone 7。

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

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内容吗? - Mathias Lykkegaard Lorenzen
我已经尝试过这个,但是没有起作用,仍然出现那个错误: s = s.Replace(Convert.ToString((byte)0x1F), string.Empty); Stream str = new MemoryStream(UTF8Encoding.UTF8.GetBytes(s)); - Nghia Nguyen
这是我尝试读取的XML文件: http://music.mobion.vn/api/v1/music/userstop?devid= - Nghia Nguyen
9个回答

18

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/


11

可能发生的情况是内容已经被压缩,这种情况下需要将其解压缩。

使用HttpHandler可以按照以下方式完成此操作:

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

对于“旧版” WebClient,您必须派生出自己的类才能实现类似的效果:

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

以上内容取自这里

如果要使用这两个,您可以这样做:

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

网络客户端

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()的好处,因为你是在使用流。


你的 HttpClient 代码对我很有效。谢谢。 - Fereshteh Mirjalili

4

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

我抄袭了这篇文章


1
我遇到了同样的问题,发现问题是XML中嵌入了一个。解决方法如下:
s = s.Replace("", " ")

0

对我来说可以运行……

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

这里的Chr是什么?没有提到Chr的参考。 - Sayed Muhammad Idrees

0
我猜这可能是一个编码问题,但如果没有看到XML,我不能确定。
关于你计划简单地替换字符但无法实现的问题,因为你有一个流而不是文本,只需将流读入字符串,然后删除你不想要的字符即可。

0
我使用XmlSerializer解析XML时遇到了相同的异常。 问题在于XML字符串包含无效字符的HTML代码。
这种方法从字符串中删除所有无效的HTML代码(基于此线程 - 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;
    }

-1
如果您不展示相关信息,那么没有人能够回答您的问题——我指的是Xml内容。
作为一般建议,我会在ReadToEnd()调用后放置一个断点。现在您可以做几件事情:
  • 向本论坛公开Xml内容。
  • 使用VS Xml可视化器进行测试。
  • 将字符串复制粘贴到txt文件中并离线调查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接