现在用 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 怎么反序列化 |