4

这是目前的情况:

我正在从 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
     }
}

当解析器遇到这个撇号时会发生崩溃: 在此处输入图像描述

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

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

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

更新:

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

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

4

4 回答 4

1

它与数据的编码有关。这使您可以获取原始二进制文件(因此编码没有问题)。

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

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

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

于 2013-06-23T11:10:26.307 回答
0

我找到了解决方案,但它有点虎头蛇尾。由于我的 API 字符串不完整,因此未检索到剧集:它应该以 结尾/all/,但我一定是在某个地方忘记了它并从那时起复制了它。这是我寻找的最后一个地方。

通过更改 API 调用,我现在可以检索所有剧集。没有更多的编码错误(尽管我没有对此进行任何更改)并且现在它已经检索了 4000 集,所以我假设其余的也不会出现问题。

有人将其设为社区 wiki:我不确定该状态是否仍然有效,因为这是一个本地化问题。不过,我从这些对话中学到了很多关于 XML/API 的知识,感谢所有参与其中的人!

于 2013-06-23T17:59:47.657 回答
0

尝试,

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

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

于 2013-06-23T01:42:34.563 回答
0

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

看起来您很可能被其中一款令人讨厌的微软产品“智能引用”,这些产品将您的所有引号和撇号更改为声称在 ISO-8859-1/Latin-1 中但实际上是 Win-1252 且带有缺少 C0 平面。如果是这种情况,只有 Win-1252 编码会为您解析该文档。或者你可以把卷曲的 apos 换成普通的,一切都会好的。

于 2013-06-23T13:46:34.773 回答