Linq to XML根据属性值选择节点

a7qyws3x  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(157)

我有一个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来填充一个“Product”类。我可以通过位置来选择元素,但是如果节点不存在,这就成了一个问题。有没有一种方法可以根据节点的属性值来选择节点?在下面的例子中,如果@name属性=“ATR_FamilyName”,我可以得到arr节点吗?在xpath中,它应该是:

doc/arr[@name = 'ATR_FamilyName']/str

下面是我的链接到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....                              
        };
aydmsdu9

aydmsdu91#

类似于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属性,你会得到一个例外。有时候例外可能更好-如果这表明数据从根本上被破坏了,并且您希望了解它,而不仅仅是与值不匹配。
(The对于XElementstring的转换也是如此。)

soat7uwm

soat7uwm2#

使用LINQ,您可以轻松地只选择具有指定属性的节点,如下所示:

var query = from node in results.Descendants("arr") // I believe you could use results.Elements("arr") here
            where node.Attribute("name").Value == "ATR_FamilyName"
            select new Product
            {
                FamilyName = node.Element("str").Value
            };
k3fezbri

k3fezbri3#

XElement的用法如下:

from rt in results.descendants("<node name>")
where rt.attribute(attribute name).value == "specified value"
select rt

抱歉用手机打字

相关问题