现在用 C#做的一个小工具里面涉及到 B 站弹幕解析的问题,B 站弹幕是 xml 格式的,遇到这种 xml 不知道怎么反序列化成对象,只能用一种效率比较低的方式去解析。
项目https://github.com/MonoLogueChi/Dplayer.Danmaku
完整 xml 示例https://api.bilibili.com/x/v1/dm/list.so?oid=1176840
xml 示例
<i>
<chatserver>chat.bilibili.com</chatserver>
<chatid>1176840</chatid>
<mission>0</mission>
<maxlimit>3000</maxlimit>
<state>0</state>
<real_name>0</real_name>
<source>e-r</source>
<d p="44.40200,4,25,3368652,1419138060,0,eb36bbaf,715944069">我炮还能再战 500 年</d>
<d p="43.25100,1,25,15138834,1419152706,0,d9a9cc2b,716265024">我炮还能再战五百年!</d>
<d p="44.82500,4,25,6723891,1419242813,0,af4aa003,717397645">我炮还能再战五百年我炮还能再战五百年</d>
<d>...</d>
</i>
其中 d 标签的 p 属性和值是需要的数据,现在用的是效率很低的一种方法,完整的方法是 https://github.com/MonoLogueChi/Dplayer.Danmaku/blob/21514b8308f129197ac92c1d7c00eb9ff4915d31/Danmaku/Utils/BiliBili/BilibiliHelp.cs
private async Task<IEnumerable<DanmakuData>> GetBiDanmakuDataAsync(string url, string cookie)
{
var client = _httpClientFactory.CreateClient("deflate");
if (!string.IsNullOrEmpty(cookie))client.DefaultRequestHeaders.Add("Cookie", cookie);
var result = client.GetStringAsync(url);
var xml = new XmlDocument();
xml.LoadXml(await result);
var ds = xml.GetElementsByTagName("d");
if (ds.Count == 0)return null;
return ds.Cast<XmlNode>().Select(s =>
{
var d = s.Attributes["p"].InnerText.Split(",");
return new DanmakuData
{
Time = float.Parse(d[0]),
Color = int.Parse(d[3]),
Type = int.Parse(d[5]),
Author = "",
Text = s.InnerText
};
});
}
我想问一下有没有更高效的一种方式,直接反序列化成
{
string P;
string Text;
}
这样的一个 List,然后再去分割 P。 我感觉肯定是有这种方式,但是微软的文档实在是有点看不懂,看示例也不知道 Attributes 怎么去搞。
我感觉无论是我现在用的 linq 还是最开始的循环取值,效率都不高。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.