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。它可以有多种类型。
我是这个网站的新手,这是我的第一个问题。我阅读了文档,但如果我违反了任何行为准则,我提前表示歉意。 这是我的问题:
我在流中有一个 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。它可以有多种类型。