aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Extensions/XmlReaderExtensions.cs
blob: cd7db91dd4bdb9bb3f419134f24670f4aadd86af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Globalization;
using System.Xml;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities;

namespace MediaBrowser.Controller.Extensions;

/// <summary>
/// Provides extension methods for <see cref="XmlReader"/> to parse <see cref="BaseItem"/>'s.
/// </summary>
public static class XmlReaderExtensions
{
    /// <summary>
    /// Parses a <see cref="PersonInfo"/> from the xml node.
    /// </summary>
    /// <param name="reader">The <see cref="XmlReader"/>.</param>
    /// <returns>A <see cref="PersonInfo"/>, or <c>null</c> if none is found.</returns>
    public static PersonInfo? GetPersonFromXmlNode(this XmlReader reader)
    {
        ArgumentNullException.ThrowIfNull(reader);

        if (reader.IsEmptyElement)
        {
            reader.Read();
            return null;
        }

        var name = string.Empty;
        var type = PersonKind.Actor;  // If type is not specified assume actor
        var role = string.Empty;
        int? sortOrder = null;
        string? imageUrl = null;

        using var subtree = reader.ReadSubtree();
        subtree.MoveToContent();
        subtree.Read();

        while (subtree is { EOF: false, ReadState: ReadState.Interactive })
        {
            if (subtree.NodeType != XmlNodeType.Element)
            {
                subtree.Read();
                continue;
            }

            switch (subtree.Name)
            {
                case "name":
                case "Name":
                    name = subtree.ReadElementContentAsString();
                    break;
                case "role":
                case "Role":
                    var roleValue = subtree.ReadElementContentAsString();
                    if (!string.IsNullOrWhiteSpace(roleValue))
                    {
                        role = roleValue;
                    }

                    break;
                case "type":
                case "Type":
                    Enum.TryParse(subtree.ReadElementContentAsString(), true, out type);
                    break;
                case "order":
                case "sortorder":
                case "SortOrder":
                    if (int.TryParse(
                        subtree.ReadElementContentAsString(),
                        NumberStyles.Integer,
                        CultureInfo.InvariantCulture,
                        out var intVal))
                    {
                        sortOrder = intVal;
                    }

                    break;
                case "thumb":
                    var thumb = subtree.ReadElementContentAsString();
                    if (!string.IsNullOrWhiteSpace(thumb))
                    {
                        imageUrl = thumb;
                    }

                    break;
                default:
                    subtree.Skip();
                    break;
            }
        }

        if (string.IsNullOrWhiteSpace(name))
        {
            return null;
        }

        return new PersonInfo
        {
            Name = name.Trim(),
            Role = role,
            Type = type,
            SortOrder = sortOrder,
            ImageUrl = imageUrl
        };
    }
}