2

给定以下 Xml 片段:

<root>
  <sheetData>
    <row r="1" />
    <row r="2" />
    <row r="3" />
    <row r="4" />
    <row r="5" />
    <row r="6" />
    <row r="7" />
  </sheetData>
</root>

可以使用以下代码创建:

XElement testElement = new XElement("root",
    new XElement("sheetData",
        new XElement("row",
            new XAttribute("r", 1)),
        new XElement("row",
            new XAttribute("r", 2)),
        new XElement("row",
            new XAttribute("r", 3)),
        new XElement("row",
            new XAttribute("r", 4)),
        new XElement("row",
            new XAttribute("r", 5)),
        new XElement("row",
            new XAttribute("r", 6)),
        new XElement("row",
            new XAttribute("r", 7))));

这是找到 r 属性为 2 的行的最佳方法吗?这行得通,但是我在 select 语句中重复了 Where 子句,我想知道是否有更好的方法和更有效的方法。

int rowNumber = 2;

XElement rowElement = testElement
    .Descendants("sheetData")
    .Where<XElement>(item => item.Descendants("row")
                                  .Where<XElement>(i => i.Attribute("r").Value == rowNumber.ToString())
                                  .FirstOrDefault<XElement>() != null)
    .Select<XElement, XElement>(item => item.Descendants("row")
                                  .Where<XElement>(i => i.Attribute("r").Value == rowNumber.ToString())
                                  .FirstOrDefault<XElement>())
    .FirstOrDefault<XElement>();

一般来说,确定 Linq to Xml 查询是否优化的最佳方法是什么?

4

3 回答 3

4

最好的方法是:

var row = testElement
   .XPathSelectElements("sheetData/row[@r='2']")
   .FirstOrDefault();

不重复Where调用的纯 LINQ 查询:

var row = testElement
    .Descendants("sheetData")
    .Descendants("row")
    .Where(x => x.Attribute("r").Value == "2")
    .FirstOrDefault();
于 2009-03-19T17:21:23.883 回答
1
//if sheetData appears multiple times
    XElement rowElement = testElement
        .Descendants("sheetData")
        .SelectMany(s=>s.Descendats("row))
        .Where(i=>i.Attribute("r").Value == rowNumber.ToString());
//if sheetData appears once
    XElement rowElement = testElement
        .Element("sheetData")
        .Descendants("row))
        .Where(i=>i.Attribute("r").Value == rowNumber.ToString());
于 2009-03-19T17:21:01.653 回答
0

您的代码中的 Select 子句不是多余的吗?WhereIEnumerable<XElement>已经返回一个。我认为

var row = testElements.Descendents("row").Where(e => (int)e.Attribute("r") == rowNumber).SingleOrDefault();

应该做你想做的

于 2009-03-19T17:22:17.577 回答