'', шестнадцатеричное значение 0x1F, является недопустимым символом. Линия 1, позиция 1 - PullRequest
15 голосов
/ 18 июля 2011

Я пытаюсь прочитать XML-файл из Интернета и разобрать его с помощью XDocument. Обычно он работает нормально, но иногда выдает ошибку за день:

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

Я пробовал некоторые решения от Google, но они не работают для VS 2010 Express 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=

Ответы [ 9 ]

16 голосов
/ 20 июля 2011

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/

4 голосов
/ 14 января 2016

Может случиться так, что содержимое сжато , и в этом случае вам необходимо распаковать его.

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

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 (), поскольку вместо этого вы работаете с потоком.

4 голосов
/ 18 июля 2011

Рассмотрите возможность использования System.Web.HttpUtility.HtmlDecode , если вы декодируете контент, считываемый из Интернета.

3 голосов
/ 11 декабря 2012

Если у вас возникли проблемы с заменой символа

Для меня возникли некоторые проблемы, если вы попытаетесь заменить, используя строку вместо символа. Я предлагаю попробовать некоторые значения тестирования, используя оба, чтобы увидеть, что они показывают. То, как вы ссылаетесь, имеет некоторый эффект.

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 голос
/ 13 апреля 2013

У меня была та же проблема, и я обнаружил, что проблема заключалась в , встроенном в XML.Решение было:

s = s.Replace("", " ")
0 голосов
/ 12 декабря 2018

Я использовал 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;
    }
0 голосов
/ 12 января 2014

у меня работает .........

string.Replace(Chr(31), "")
0 голосов
/ 18 июля 2011

Я думаю, это, вероятно, проблема с кодировкой, но я не могу сказать точно, не видя XML.

С точки зрения вашего плана просто заменить символ, но не в состоянии, потому что у вас естьпоток, а не текст, просто прочитайте поток в строку и затем удалите ненужные символы.

0 голосов
/ 18 июля 2011

Никто не может ответить, если вы не показываете соответствующую информацию - я имею в виду содержимое XML.

В качестве общего совета я бы поставил точку останова после вызова ReadToEnd ().Теперь вы можете сделать несколько вещей:

  • Показать XML-контент на этом форуме.
  • Протестируйте его с помощью визуализатора VS Xml.
  • Скопируйте и вставьте строку в текстовый файл и исследуйте ее в автономном режиме.
...