解析.xspf文件时XmlDocument
报“根元素缺失”错误
常见原因是文件开头有BOM(字节顺序标记)或空白字符,而
XmlDocument.Load()对BOM敏感。直接传路径进去容易崩,尤其Windows记事本另存的.xspf常带UTF-8 BOM。 改用
XmlDocument.Load(XmlReader.Create(filePath, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore })),绕过BOM检测
更稳妥的做法:先用File.ReadAllBytes()读取,用
new MemoryStream()喂给
XmlReader,并显式指定
Encoding.UTF8别依赖
File.ReadAllText()再
LoadXml()——换行符、引号转义、未闭合标签都会让
LoadXml()直接抛
XmlException
XElement
解析trackList
时漏掉嵌套location
节点
.xspf里每个
<track></track>下可能有多个
<location></location>(比如主备地址),但VLC只认第一个;而有人误用
Element("location").Value,一旦该track没写
location就返回
null,不报错但值为空。 必须用
Elements("location").FirstOrDefault()?.Value,避免NullReferenceException
注意命名空间:XNamespace ns = "http://xspf.org/ns/0/";,查节点得写
ns + "track",否则
Elements()找不到任何东西 VLC实际只读第一个
location,但规范允许多个,所以解析时别自动拼接或去重——保留原结构,由上层逻辑决定用哪个
生成.xspf文件时XmlWriter
输出不符合VLC识别要求
VLC对.xspf的格式其实挺挑:必须声明
xmlns,
<playlist></playlist>要有
version="1"属性,且
<tracklist></tracklist>不能空——哪怕没曲目也得留个空标签,否则VLC加载失败静默失败。 用
XmlWriter.Create()时设
new XmlWriterSettings { Indent = true, OmitXmlDeclaration = false },声明行不能丢
手动写<playlist version="1" xmlns="http://xspf.org/ns/0/"></playlist>,别靠
XElement.Save()自动生成——它默认不写
version属性 即使没有音轨,也要写
<tracklist></tracklist>,空集合不能跳过这个标签
用Process.Start()
调VLC打开.xspf,中文路径乱码
不是编码问题,是VLC命令行参数本身不支持宽字符传参(尤其在旧版3.0.x)。直接拼路径传过去,遇到中文目录名,VLC内部解码成
,然后报“file not found”。 把.xspf文件路径转成短路径(GetShortPathName()API),绕过Unicode传参缺陷 或者改用
ProcessStartInfo.UseShellExecute = true,再配合
ProcessStartInfo.Verb = "open",走系统关联打开(前提是.vlc已关联.xspf) 绝对别用
Uri.EscapeDataString()编码路径——VLC不认URL编码,只会当成文件名的一部分 VLC的.xspf支持其实卡在XSPF 1.0规范子集里,像
meta扩展字段、
link、
annotation这些全被忽略。真正要稳定控制播放行为,得靠VLC的HTTP接口或libvlc绑定,而不是死磕.xspf格式细节。
