C# Query XML with Linq to find match

C# Query XML with Linq to find match

这是我的 XML 的一个片段(只有几个条目,但实际上有大约一千个条目)。

<?xml version="1.0" encoding="UTF-8"?>
<information_code version="3.5">
  <entry code="000" title="Function, data for plans and description"/>
  <entry code="001" title="Title page"/>
  <entry code="002" title="List of pages or data modules"/>
  <entry code="003" title="Change records and highlights"/>
  <entry code="004" title="Access illustration"/>
</information_code>

我需要做的是将 'code' 属性与我传递到查询中的值相匹配,然后 return 'title' 属性的值。确实应该不难,但是我在兜圈子。

这是我目前所在的位置,但总是在没有匹配的情况下被抓到。显然我的查询有问题。

private string getInfoName(string infoCode)
{
    XDocument mydoc = XDocument.Load(GlobalVars.pathToInfoCodes);
    string name = string.Empty;

    try
    {
        var entry = mydoc
            .Elements("entry")
            .Where(e => e.Attribute("code").Value == infoCode)
            .Single();

        name = entry.Attribute("title").Value;
    }
    catch
    {
        MessageBox.Show("Info code not recognised: " + infoCode);
    }        
   return name;
}

问题是,当您使用 Elements 时,它只会搜索您当前所在的级别,此时是 <information_code> - 因此没有 <entry> 元素那里。

您可以使用 .Element("information_code").Elements("entry") 或使用 .Descendants:

string wantedCode = "001";

var title = XDocument.Load(GlobalVars.pathToInfoCodes)
         .Descendants("entry")
         .Where(e => e.Attribute("code")?.Value == wantedCode)
         .Select(e => e.Attribute("title").Value).FirstOrDefault();

您也可以使用查询语法来完成。可能看起来更好:

var title = (from e in XDocument.Load("data.xml").Descendants("entry")
             where e.Attribute("code")?.Value == wantedCode
             select e.Attribute("title")?.Value).FirstOrDefault();

请注意,?. 语法是 C# 6.0 Null Propagation。如果您使用的是较早的 C# 版本,则必须将属性存储在变量中,检查它是否不是 null,然后才访问 .Value