现在用 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 还是最开始的循环取值,效率都不高。
1
ragnaroks 2019-10-22 21:02:35 +08:00
看下前端的 js 解码方法?
这种数据乍一看我也可能会一个个匹配 |
2
vibbow 2019-10-22 21:06:09 +08:00
第一想到的就是使用 xslt,或者 xpath
|
3
MonoLogueChi OP @ragnaroks 感觉这样取不太优雅,虽然能用,但还是想学一下这样的 xml 怎么反序列化
|