'', шестнадцатеричное значение 0x1F, является недопустимым символом. Строка 1, позиция 1

Я пытаюсь прочитать 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

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

Ответ 2

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

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

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

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

Я заметил это

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

Работает для меня.........

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

Ответ 8

Я использовал XmlSerializer для разбора XML и столкнулся с тем же исключением. Проблема в том, что строка XML содержит коды HTML недопустимых символов

Этот метод удаляет все недопустимые HTML-коды из строки (на основе этой темы - https://forums.asp.net/t/1483793.aspx?Need+a+method+that+removes+illegal+XML+characters+from+a + Строка):

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

Ответ 9

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

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

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