我正在尝试从Web读取xml文件并使用XDocument解析它。它通常工作正常,但有时它会给我这一天的错误:
**' ', hexadecimal value 0x1F, is an invalid character. Line 1, position 1**
我尝试了一些谷歌的解决方案,但它们不适用于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;
}
}
答案 0 :(得分: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/
答案 1 :(得分:4)
如果要解码从网络上读取的内容,请考虑使用System.Web.HttpUtility.HtmlDecode。
答案 2 :(得分: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
答案 3 :(得分:3)
可能会发生的内容是压缩,在这种情况下您需要将其解压缩。
使用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);
}
}
}
}
}
<强> Web客户端强>
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 :(得分:1)
我遇到了同样的问题,发现问题是嵌入在xml中的
。
解决方案是:
s = s.Replace("", " ")
答案 5 :(得分:0)
我猜这可能是一个编码问题,但没有看到我无法肯定的XML。
就你的简单替换角色但无法使用的计划而言,因为你有一个流而不是一个文本,只需将流读入一个字符串然后删除你不想要的字符。
答案 6 :(得分:0)
为我工作.........
string.Replace(Chr(31), "")
答案 7 :(得分: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;
}
答案 8 :(得分:-1)
如果您没有显示相关信息,则无人可以回答 - 我的意思是Xml内容。
作为一般建议,我会在ReadToEnd()调用后设置一个断点。现在你可以做几件事: