using System; using System.Collections.Generic; using System.Xml; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Providers; using Microsoft.Extensions.Logging; namespace MediaBrowser.LocalMetadata.Parsers { /// /// Playlist xml parser. /// public class PlaylistXmlParser : BaseItemXmlParser { /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. public PlaylistXmlParser(ILogger logger, IProviderManager providerManager) : base(logger, providerManager) { } /// protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult itemResult) { var item = itemResult.Item; switch (reader.Name) { case "PlaylistMediaType": if (Enum.TryParse(reader.ReadNormalizedString(), out var mediaType)) { item.PlaylistMediaType = mediaType; } break; case "PlaylistItems": if (!reader.IsEmptyElement) { using (var subReader = reader.ReadSubtree()) { FetchFromCollectionItemsNode(subReader, item); } } else { reader.Read(); } break; default: base.FetchDataFromXmlNode(reader, itemResult); break; } } private void FetchFromCollectionItemsNode(XmlReader reader, Playlist item) { var list = new List(); reader.MoveToContent(); reader.Read(); // Loop through each element while (!reader.EOF && reader.ReadState == ReadState.Interactive) { if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { case "PlaylistItem": { if (reader.IsEmptyElement) { reader.Read(); continue; } using (var subReader = reader.ReadSubtree()) { var child = GetLinkedChild(subReader); if (child is not null) { list.Add(child); } } break; } default: reader.Skip(); break; } } else { reader.Read(); } } item.LinkedChildren = list.ToArray(); } } }