V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
MonoLogueChi
V2EX  ›  问与答

问一个关于 XML 反序列化的问题

  •  
  •   MonoLogueChi · 2019-10-22 18:01:32 +08:00 · 1127 次点击
    这是一个创建于 1892 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在用 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 还是最开始的循环取值,效率都不高。

    3 条回复    2019-10-22 21:22:30 +08:00
    ragnaroks
        1
    ragnaroks  
       2019-10-22 21:02:35 +08:00
    看下前端的 js 解码方法?

    这种数据乍一看我也可能会一个个匹配
    vibbow
        2
    vibbow  
       2019-10-22 21:06:09 +08:00
    第一想到的就是使用 xslt,或者 xpath
    MonoLogueChi
        3
    MonoLogueChi  
    OP
       2019-10-22 21:22:30 +08:00 via Android
    @ragnaroks 感觉这样取不太优雅,虽然能用,但还是想学一下这样的 xml 怎么反序列化
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3344 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 00:44 · PVG 08:44 · LAX 16:44 · JFK 19:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.