c# Linq for XML : tag.descendants 不允许询问所有后代

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

我是这个网站的新手,这是我的第一个问题。我阅读了文档,但如果我违反了任何行为准则,我提前表示歉意。 这是我的问题:

我在流中有一个 XML 文件。我的目标是获取属性 "Name"、"Type" 和一个或多个键(由于显而易见的原因,它们已被更改)。

<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>

我创建了一个 class 来保存数据

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

我创建了一个 MsProduct 的列表,将 var list 的每个元素(见后面)添加到我的对象中。

我创建了一个 Linq 查询,它在没有 Key = (List<string>)keys 的情况下编译,但我只得到值 Name, Type 是空的(我检查数据是否不存在(即 ==空),它用“”代替它)。

当我添加 Key = (List<string>)keys 时,系统抛出一个 "System.InvalidCastException"。

这是我的查询:

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
                   };

有谁知道如何查询我的文件以填充我的 class?

提前致谢!

您的密钥不是字符串,而是 XElements,您无法将其转换为 string。根据你想得到什么,你可以这样做:

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

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

但是您在 xml 上什么也得不到,因为您查询的不是产品,而是 YourKey 的,要获取产品,请将第一行更改为:

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

如果你想得到类型,你应该考虑,你有不止一种类型专业产品。要么你将类型作为键查询到列表,要么你确定它们都是相同的,所以你可以只取第一个:

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()
           };

您不需要那些 let 语句。您确实需要从密钥中获取值。

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()
               };

但是Elements("Type").First()当然是一个有问题的定义。
没有 类型的 ProductKey。它可以有多种类型。