假设您有一个像这样的 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/