Home

Recursive Linq

edited January 10

Hi i have the following problem:
I have a XML File and i want to build c# objects in a list.
The Problem is that some of the entries are outdated and have a "deprecated" and a "replacement" Attribute.
In my List of objects i want to get a reference on the replaced Object.
For Example:

------Start XML Content:

<pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="BGM21_DFP" version="5.8.10" deprecated="2019-11-12" replacement="SiliconLabs.GeckoPlatform_BGM21_DFP" />
<pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="GeckoPlatform_BGM13_DFP" version="4.3.0" />
<pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="GeckoPlatform_BGM21_DFP" version="4.3.0" />  

Stop XML Content-------

------ Start Linq Query:

    XDocument doc = XDocument.Load(xmlFile);
    var query1 = from c in doc.Descendants("pdsc")
                 select new PackageDescription
                 {
                     Name = c.Attribute("name").Value,
                     Url = Uri.TryCreate(c.Attribute("url").Value, UriKind.Absolute, out _) ? new Uri(c.Attribute("url").Value) : null,
                     Vendor = c.Attribute("vendor").Value,
                     Version = c.Attribute("version").Value,
                     Deprecated = c.Attribute("deprecated") != null ? DateOnly.Parse(c.Attribute("deprecated").Value) : null,
                 };

    var list = query1.ToList();

End Linq Query ------

Is there an elegant way to write the query?
Bests
Brian

Comments

  • edited January 17

    Here could be the answer, with whole examples:

    void Main()
    {
        var xml = """
        <?xml version="1.0" encoding="utf-8"?>
        <root>
        <pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="BGM21_DFP" version="5.8.10" deprecated="2019-11-12" replacement="SiliconLabs.GeckoPlatform_BGM21_DFP" />
        <pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="GeckoPlatform_BGM13_DFP" version="4.3.0" />
        <pdsc url="https://www.silabs.com/documents/public/cmsis-packs/" vendor="SiliconLabs" name="GeckoPlatform_BGM21_DFP" version="4.3.0" />  
        </root>
        """;
    
        XDocument doc = XDocument.Parse(xml);
        var query1 = from c in doc.Descendants("pdsc")
                     select new PackageDescription
                     {
                         Name = c.Attribute("name").Value,
                         Url = Uri.TryCreate(c.Attribute("url").Value, UriKind.Absolute, out _) ? new Uri(c.Attribute("url").Value) : null,
                         Vendor = c.Attribute("vendor").Value,
                         Version = c.Attribute("version").Value,
                         Deprecated = c.Attribute("deprecated") != null ? DateOnly.Parse(c.Attribute("deprecated").Value) : null,
                         Replacement = c.Attribute("replacement")?.Value,
                         References = null
                     };
    
        var list = query1.ToList();
        var namedDic = list.GroupBy(x => x.Name, x => x).ToDictionary(x => "SiliconLabs." + x.Key, x => x.ToList());
        var ret = list.Select(x => x with { References = x.Replacement == null ? null : namedDic[x.Replacement] });
    
        list.Dump();
        namedDic.Dump();
        ret.Dump();
    }
    
    public readonly record struct PackageDescription(string Name, Uri Url, string Vendor, string Version, DateOnly? Deprecated, string Replacement, IReadOnlyList<PackageDescription> References)
    { }
    
    
Sign In or Register to comment.