c# - 基本 LINQ 语法

标签 c# xml linq parent-node

假设您有一个像这样的 XML:

 <data>
  <messages>
   <message name="Person" id="P">
    <field name="FirstName" required="Y" />
    <field name="LastName" required="Y" />
    <field name="Sex" required="N" />
   </message>
   <message name="Car" id="C">
    <field name="Make" required="Y" />
    <field name="Model" required="Y" />
    <field name="Year" required="N" />
   </message>
  </messages>
 </data>

使用 Linq,您如何获得 Person 所有必填字段名称的列表?

我今天才开始玩 LINQ/XML,这大概是我所了解的。

    var q = from c in loaded.Descendants("field")
            where (string)c.Attribute("required") == "Y" &&
            // how to check the parent node (message) has an attribute (id="P")           
            select (string)c.Attribute("name");

    foreach (string name in q)
        Console.WriteLine(name);

最佳答案

我为消息添加了根元素和结束标记以使 XML 有效:

XDocument loaded = XDocument.Parse(@"
  <messages>
    <message name=""Person"" id=""P"">
      <field name=""FirstName"" required=""Y"" />
      <field name=""LastName"" required=""Y"" />
      <field name=""Sex"" required=""N"" />
    </message>
    <message name=""Car"" id=""C"">
      <field name=""Make"" required=""Y"" />
      <field name=""Model"" required=""Y"" />
      <field name=""Year"" required=""N"" />
    </message>
  </messages>");

与其查找所有字段然后检查每个字段的父级,不如查找您感兴趣的一个父级,这样您要检查的字段就更少了:

IEnumerable<string> fields =
  loaded.Root.Elements()
  .Where(m => m.Attribute("id").Value == "P")
  .Single()
  .Elements("field")
  .Where(f => f.Attribute("required").Value == "Y")
  .Select(f => f.Attribute("name").Value);

编辑:
为子元素添加了说明符“字段”,以防消息元素包含任何其他类型的元素。

编辑 2:
我将一个工作示例与实际数据的一个子集放在一起:

XDocument loaded = XDocument.Parse(@"
  <fix major=""4"" minor=""4"">
    <header>
    </header>
    <trailer>
    </trailer>
    <messages>
      <message name=""ResendRequest"" msgtype=""2"" msgcat=""admin"">
        <field name=""BeginSeqNo"" required=""Y"" />
        <field name=""EndSeqNo"" required=""Y"" />
      </message>
      <message name=""Reject"" msgtype=""3"" msgcat=""admin"">
        <field name=""RefSeqNum"" required=""Y"" />
        <field name=""RefTagID"" required=""N"" />
        <field name=""RefMsgType"" required=""N"" />
        <field name=""SessionRejectReason"" required=""N"" />
        <field name=""Text"" required=""N"" />
        <field name=""EncodedTextLen"" required=""N"" />
        <field name=""EncodedText"" required=""N"" />
      </message>
    </messages>
  </fix>");

IEnumerable<string> fields =
  loaded.Root.Element("messages").Elements("message")
  .Where(m => m.Attribute("name").Value == "Reject")
  .Single()
  .Elements("field")
  .Where(f => f.Attribute("required").Value == "Y")
  .Select(f=>f.Attribute("name").Value);

关于c# - 基本 LINQ 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1690019/

相关文章:

c# - 通过Unity引用python脚本

c# - 静态 session 类和多用户

c# - 反序列化xlink :href

xml - 检查/解决单独 xml 文件中的交叉引用

Linq to SharePoint 抛出空引用异常

c# - 延期执行会不会先调用Dispose导致失败?

c# - Linq 查询 ToList() 运行

java - 如何让Android Studio中的actionbar消失?

c# - 表达式树中未发生隐式转换

c# - 使用 linq 检查 ILookup<string, string> 中的键值是否存在的最佳方法