尽管编码,XML Parser仍然会遇到特殊字符

时间:2013-06-23 00:21:55

标签: c# xml

情况就是这样:

我正在从XML API接收数据。此数据有时包含特殊的撇号字符,这会导致我的解析器崩溃。只有当我从本地文件中读取数据时才会发生此崩溃。当我从流中读取数据时没有崩溃,但我也没有得到DOM树:它退出而没有通知我。

您将在下面找到我们为使事情发挥作用而进行的尝试列表:

// Does not work
var web = new WebClient();
web.Encoding = Encoding.UTF8;
var response = web.DownloadString("http://thetvdb.com/api/apikey/series/" + show.TVDBID + "/");
var tree = XDocument.Parse(response);

// Works
var doc = new XmlDocument();
doc.Load("C:\\Test\\test.xml");
var response = doc.InnerXml;
var tree = XDocument.Parse(response);

// Works
var xmlDoc = XDocument.Parse(File.ReadAllText("c:\\Test\\test.xml", System.Text.Encoding.UTF8));
var xmlDoc = XDocument.Load("C:\\Test\\test.xml");
var tree = xmlDoc;

// Does not work
var web = new WebClient();
web.Encoding = Encoding.UTF8;
web.DownloadFile("http://thetvdb.com/api/apikey/series/" + show.TVDBID + "/", "C:\\test.xml");
var tree = XDocument.Load("C:\\test.xml");

// Does not work
var web = new WebClient();
web.Encoding = Encoding.UTF8;
var data = web.DownloadData("http://thetvdb.com/api/apikey/series/" + show.TVDBID + "/");
var response = Encoding.UTF8.GetString(data);
var tree = XDocument.Parse(response);

我根据它是否到达此循环的第一行中的断点来确定某些东西是否有效:

if (root != null) { 
     var lastupdate = root.Element("Series").Element("lastupdated").Value;

     foreach (var epi in tree.Descendants("Episode")) {
          var season = epi.Element("SeasonNumber").Value; // Breakpoint here
     }
}

当解析器遇到这个撇号时发生崩溃: enter image description here

当我用我自己手动输入的撇号或&#39替换此字符时,不再抛出错误,它会继续直到下一个。 当我在firefox和chrome中查看API请求的源页面时,它告诉我编码是UTF-8,API维基上的代码示例也在标题中显示UTF-8。

这是我到目前为止的地方。有任何想法吗?

我刚刚注意到,API查询中的结果字符串在调试期间根据XML / Text / HTML可视化工具仅包含<Series></Series>标记,而没有<Episode></Episode>个。但是,当我在浏览器中执行相同的查询时,它会向我显示两者。这可能吗?当我通过Postman看它时,会显示剧集。

更新

当我使用Unicode作为编码时,我没有收到任何警告,我可以完全解析本地xml文件!我不是编码专家,使用Unicode有什么缺点吗?

当对数据流使用unicode时,我得到了一堆亚洲字符。

4 个答案:

答案 0 :(得分:1)

它与数据的编码有关。这允许您获得原始二进制(因此编码没有问题)。

WebClient myWebClient = new WebClient();
byte[] data = myWebClient.DownloadData(uri);

string xmlContents = Encoding.UTF8.GetString(data);

编辑根据您最近使用Unicode的发展,我会说数据实际上是用UTF-16编码的。 Unicode不是一种编码类型,它本质上只是一个编码字符集 - 即一组字符和字符与表示它们的整数代码点之间的映射。当你“用Unicode编码某些东西”时,它通常意味着UTF-16。无论如何,很高兴您的问题得到解决!

答案 1 :(得分:0)

尝试,

var tree = XElement.Parse(response);
foreach(var epi in tree.Descendants("Episode"))
{
   ...
}

如果Data是您的根节点并且没有隐藏的Episode,那么您可以用元素替换Descendants。

答案 2 :(得分:0)

&#39是某些浏览器的html转义符。请改用&apos;,它是正确的xml转义序列。

你可能会被那些令人讨厌的微软产品“智能引用”,这些微软产品会将你的所有引号和撇号改为声称属于ISO-8859-1 / Latin-1的卷曲产品,但实际上是Win- 1252缺少C0平面。如果是这种情况,只有Win-1252编码才会为您解析该文档。或者你可以为常规的一个关掉卷曲的一个,一切都会好的。

答案 3 :(得分:0)

我找到了解决方案,但它有点具有反作用。因为我的API字符串不完整而没有检索到剧集:它应该以{{1​​}}结束,但我必须忘记它并从那一点向前复制。这是我看的最后一个地方。

通过更改API调用,我现在可以检索所有剧集。 没有更多的编码错误(即使我没有改变),现在它已经检索了4000集,所以我假设其余的也没有问题。

有人认为这是一个社区维基:我不确定这种状态是否仍有必要,因为这是一个本地化的问题。我从这些对话中学到了很多关于XML / API的知识,感谢所有参与者!

相关问题