LINQ to XML 在 xml 中查找特定类别

LINQ to XML to find a specific category in xml

我有以下 xml:

<table name="transactions">
    <row>
        <col name="id">1</col>
        <col name="amount">2673.9</col>
        <col name="created_date">2014-10-19</col>
        <col name="display_date">2014-04-22</col>
        <col name="cat_id">13</col>
        <col name="note">Initial Balance</col>
        //other col tags
    </row>
    <row>
        ...
    </row>
</table>

我需要查找具有特定 cat_id 的所有行。 LINQ 查询会是什么样子?我试过了

IEnumerable<XElement> rows = 
    from el in root.Elements("row")
    where (string)el.Element("col").Attribute("name") == "cat_id"
    select el;

但它returns没什么。

首先,您需要了解如何编写 LINQ 查询。

如果你读过documentation,你就会知道Element()方法return是第一个匹配元素,在这种情况下,<col name="id">1</col>行是return编辑。由于第一个匹配元素中名为 "name" 的属性没有值 "cat_id",它会移动到下一个 row 元素。

如果每次都确保 "cat_id" 是第一个匹配元素,您的查询就可以工作。

如果您不能确定或无法进行更改,您首先需要搜索名为 "cat_id" 的 所有 属性,然后使用特定值。

首先,要获取所有子元素,需要改用Elements()方法。然后您需要查找特定的属性名称和值。

IEnumerable<XElement> rows = from el in xdocument.Root.Elements("row")
                             from col in el.Elements("col")
                             where (string)col.Attribute("name") == "cat_id"
                             where col.Value =="13"
                             select el;

此查询将 return 具有 col 元素且属性名为 name 且值为 cat_id 的所有行。然后仅当具有 cat_id 属性的元素的值为 13.

假设 root 是您的 XElement "table" 您的 where 子句选择每个 "row" 中的第一个 XElement "col"。 for "col" 元素的属性是 "id",它永远不等于 "cat_id".

你要做的是:

XDocument xmlDoc = XDocument.Load("test.xml");
XElement root = xmlDoc.Element("table");
Dictionary<string, List<XElement>> s1 = root.Elements("row")
                                            .GroupBy(ks => ks.Elements("col").Single(p => p.Attribute("name").Value == "cat_id").Value)
                                            .ToDictionary(ks => ks.Key, es => es.ToList());

它给你一个字典,其中 cat_ids 作为键,每个键 XElement 行的列表

在这个例子中,我没有考虑没有名称属性的列和缺少 cat_id 的行 - 这会给你 NullReferenceExceptions,你需要在查询中处理表达式