我有一个 xml 文件,它返回一组由属性值唯一的元素。这会带来一个问题,因为我无法通过名称选择节点:
<doc>
<float name="score">1.2873721</float>
<arr name="2_category">
<long>3021</long>
</arr>
<arr name="ATR_FamilyName">
<str>Some Cookbook </str>
</arr>
<arr name="ATR_IsFamily">
<str>0</str>
</arr>
<arr name="ATR_SellPrice">
<str>49.95</str>
</arr>
<arr name="ATR_VendorId">
<str>ABC</str>
</arr>
<arr name="ATR_VendorName">
<str>WROX</str>
</arr>
</doc>
我正在使用 linq 来填充“产品”类。我可以按位置选择元素,但是如果节点不存在,这就会成为一个问题。有没有办法根据节点的属性值来选择节点?在下面的示例中,如果 @name 属性 = "ATR_FamilyName",我可以获取 arr 节点吗?在 xpath 中它将是:
doc/arr[@name = 'ATR_FamilyName']/str
这是我的 linq to xml 查询:
var query = from rt in results
where (String)rt.Descendants().ElementAt(5).Element("str").Value == "0"
select new Product.Product
{
FamilyName = (String)rt.Descendants().ElementAt(3).Value
// doc/arr[@name = 'ATR_FamilyName']/str - select Family Name is arr/@name 'ATR_FamilyName'
MorePropertiestoset....
};
最佳答案
类似于 AS-CII 的答案,但不使用查询表达式(外部表达式除外),并使用 XAttribute
的转换,并选择 str
元素值在匿名类型中:
select new Product.Product
{
FamilyName = rt.Descendants("arr")
.Where(x => (string) x.Attribute("name") == "ATR_FamilyName")
.Select(x => (string) x.Element("str"))
.FirstOrDefault(),
MorePropertiesToSet....
};
请注意,对 Attribute("name")
的调用结果使用强制转换意味着如果有任何元素没有属性,转换将导致空引用(不等于字符串文字)。如果您使用 Value
属性,您将得到一个异常。有时异常可能会更好 - 如果这表明数据已从根本上损坏并且您想了解它而不是仅仅不匹配该值。
(同样适用于将 XElement
转换为 string
。)
关于c# - Linq to XML 根据属性值选择节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7892488/