我为消息添加了一个根元素和结束标记,以使 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);