【问题标题】:Returning Element Values by Attribute Using C# and Linq使用 C# 和 Linq 按属性返回元素值
【发布时间】:2014-11-12 06:42:57
【问题描述】:

我对使用 LINQ 非常陌生。我有以下 XML:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <RetentionValue code="NR" fullName="Normal Retention">Used for normal retention periods commonly expressed as only numbers (i.e. "25" for 25 years).</RetentionValue>
  <RetentionValue code="SR" fullName="Short Retention">Used for short retention periods expressed in terms of months (i.e. "6 months").</RetentionValue>
  <RetentionValue code="AR" fullName="Annual Review">Review annually and retain what is needed, dispose of what is not needed.</RetentionValue>
  <RetentionValue code="PE" fullName="Permanent">Document is to be retained permanently.</RetentionValue>
  <RetentionValue code="EX" fullName="Expiration">Disposal date is calculated from expiration of a contract, loan, or other such instrument.</RetentionValue>
  <RetentionValue code="LI" fullName="Lifetime">Disposal date is calculated from the end-of-life date for a piece of equipment or other asset (e.g. software application).</RetentionValue>
  <RetentionValue code="TE" fullName="Employee Termination">Disposal date is calculated from the date of termination or retirement of an employee.</RetentionValue>
  <RetentionValue code="FR" fullName="Final Resolution">Disposal date is calculated from the date of final resolution for an issue.</RetentionValue>
</root>

在我的代码中,我创建了一个具有属性RetentionEvent 的对象,该属性的值是上述两个字母代码之一。我想找到具有匹配属性的元素,然后将fullName 返回到一个文本字段,并将值(冗长的描述)返回到另一个文本字段。到目前为止,我有以下内容:

// Construct a RecordDisposal object by passing it a valid retention code.
// An exception will be thrown if the code is not valid.
_rd = new RecordDisposal(RetentionCode.Text);
// Load up XML file with description of codes.
XDocument rangeValues = XDocument.Load("DisposalRangeValues.xml");
XElement codeValue = rangeValues.Root.Elements().Single(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent);
CodeName.Text = codeValue.Attribute("fullName").Value.ToString();
CodeDescription.Text = codeValue.Value.ToString();

查询是this 代码的直接模式(我认为),但是我遇到了一些我不明白的错误:“查询正文必须以选择子句或组结尾子句”(我认为这就是 ToList() 的用途),并且 “select 子句中的表达式类型不正确。调用 'Select' 时类型推断失败。” em> 不幸的是,我对 Linq 的理解不够好,无法解决此问题,并且“有关此错误的帮助”没有任何用处。

我做错了什么?另外,我怀疑ToList() 函数会返回一些在ToString() 函数中渲染效果不佳的东西,但我一直在等着弄清楚其他东西,然后再愚弄它。如果有人有建议,请提供。

编辑:根据以下建议修改代码以使用 Single。发现rangeValues 正在将所有&lt;root&gt; 作为单个节点加载。

EDIT2:想通了。修改代码以改用rangeValues.Root.Elements()。更新了上面的代码以反映。

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    稍微重新格式化,你的代码看起来像这样:

    XElement codeValue =
        from fullName
        in rangeValues.Elements()
                      .Where(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent)
                      .ToList();
        // select ???
    

    因此ToList() 应用于查询的in 部分,但您缺少select 语句。

    实际上,由于您希望返回单个 XElement,因此您可能想要这样的东西,它选择集合中与 Single() 中指定的子句匹配的唯一元素:

    XElement codeValue =
        (from fullName in rangeValues.Elements()
         where (string)fullName.Attribute("code") == _rd.DisposalList[0].RetentionEvent
         select fullName).Single();
    

    替代语法(以上为查询语法,以下称为方法语法):

    XElement codeValue =
        rangeValues.Elements().Single(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent);
    

    如果可能没有匹配项,或者可能不止一个匹配项,您还需要研究 SingleOrDefault()First()FirstOrDefault()

    【讨论】:

    • 我喜欢Single() 方法,正如您所怀疑的,不想要SingleOrDefault() 或其他任何一个提供的方法。但是,当我知道它确实存在时,我会抛出一个异常,说 "Sequence contains no matching element"。好吧,至少我知道价值是代表的。 XML 是否正确加载和解析是另一回事。
    • 知道了。需要使用rangeValues.Root.Elements()
    【解决方案2】:

    您的 .ToList() 调用正确,但 LINQ 查询的语法不正确。

    试试这个:

    List<XElement> fullnames = (from fullName in rangeValues.Elements()
                                where fullName.Attribute("code") == _rd.DisposalList[0].RetentionEvent
                                select fullName).ToList();
    

    【讨论】:

    • 这很好,但在我的情况下,Single() 方法效果更好。
    猜你喜欢
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多