简体   繁体   中英

c# Linq for XML : tag.descendants doesn't allow to interrogate all descendents

I'm fairly new on this website, it's my first question. I read the documentation, but I'm sorry in advance if I brake any code of conduct. Here is my question :

I have an XML file in a stream. My goal is to get the attribute "Name", "Type", and the key or keys (they've been changed for obvious reason ).

<YourKey>
<Product_Key Name="eMbedded Visual C++ 4.0">
<Key ID="5" Type="Static Activation Key" ClaimedDate="">BBBBB-QW36D-DPT6T-BBBB-ZZZZZ</Key>
</Product_Key>
<Product_Key Name="Windows 10 Home">
<Key ID="1251" Type="Retail" ClaimedDate="1/25/2017">ZZZZZ-6GBG7-ZZZZZ-8JG23-FM47H</Key>
<Key ID="1251" Type="Retail" ClaimedDate="8/23/2016">FEFEF-FVD7K-EEEEF-BEBEB-VMHX7</Key>
<Key ID="1251" Type="Retail" ClaimedDate="4/28/2016">EEZZE-GYB6P-ZZZEE-R72PQ-EEEEZ</Key>
</Product_Key>
</YourKey>

I created a class to hold the data

public class MsProduct
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public List<string> key { get; set; }
    }

And I created a list of MsProduct to add every elements of var list (see after) to my object.

I created a Linq query, it compiles without the Key = (List<string>)keys , but I only get the value Name, Type is empty (I have a check if the data doesn't exists(ie == null), it replace it by " ").

When I add the Key = (List<string>)keys , the system throws a "System.InvalidCastException".

here is my query :

var productName = XDocument.Load(fileXml);
var list = from product in productName.Descendants("YourKey")
                   let name = product.Attribute("Name")
                   let type = product.Attribute("Type")
                   let keys = product.Elements("Key")
                   select new MsProduct
                   {
                       Name = (string)name,
                       Type = (string)type,
                       Key = (List<string>)keys
                   };

Does anyone have any idea how to query my file in order to populate my class?

Thanks in advance!

Your keys are not strings, but XElements , you couldn't cast it to string . Depending on what do you want to get, you could do:

 Key = (List<string>)keys.Select(x=>x.Value).ToList()

or

 Key = (List<string>)keys.Select(x=>x.ToString()).ToList()

But you will get nothing on your xml, because you query not products, but YourKey 's , to get products change first line to:

var list = from product in productName.Descendants("Product_Key")

If you want to get the type, you should consider, that you have more than one Type pro product. Either you query types to the list as keys, or you are sure they all are the same, so you could take just the first one:

var list = from product in productName.Descendants("Product_Key")
           let name = product.Attribute("Name")            
           let keys = product.Elements("Key")
           select new MsProduct
           {
               Name = (string)name,
               Type = keys.First().Attribute("Type").Value,
               Key = (List<string>)keys.Select(x=>x.Value).ToList()
           };

You don't need those let statements. You do need to get the values form your keys.

var list = from product in productName.Descendants("Product_Key")
               where product.Attribute("Name").Value == "YourKey"
             //  let name = product.Attribute("Name")
             //  let type = product.Attribute("Type")
             //  let keys = product.Elements("Key")
               select new MsProduct
               {
                   Name = (string)product.Attribute("Name"),
                   Type = product.Elements("Type").First().Attribute("Type").Value,
                   Key = product.Elements("Key").Select(e=>e.Value).ToList()
               };

But Elements("Type").First() is of course a questionable definition.
There is no such thing as the Type of a ProductKey. It can have many Types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM