如何使用DescendantsUntil()提取XML中多层嵌套的Member元素?
提取XML中所有层级的
<Member>元素(含嵌套结构) 之前使用DescendantsUntil()扩展方法仅能定位顶层<Member>元素及其直接子元素,现在需要处理多层嵌套的XML结构,提取所有层级的<Member>元素(包括父级、子级、孙级等所有嵌套的Member节点)。
示例XML结构
<?xml version="1.0" encoding="utf-8"?> <Document> <Interface> <Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v4"> <Section Name="Static"> <Member Name="3bool1" Datatype=""3bool"" Remanence="NonRetain" Accessibility="Public"> <AttributeList> <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="SetPoint" SystemDefined="true">false</BooleanAttribute> </AttributeList> <Sections> <Section Name="None"> <Member Name="bool1" Datatype="Bool" /> <Member Name="bool2" Datatype="Bool" /> <Member Name="bool3" Datatype="Bool" /> <Member Name="3bool1" Datatype=""3bool"" Remanence="NonRetain" Accessibility="Public"> <AttributeList> <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="SetPoint" SystemDefined="true">false</BooleanAttribute> </AttributeList> <Sections> <Section Name="None"> <Member Name="bool1" Datatype="Bool" /> <Member Name="bool2" Datatype="Bool" /> <Member Name="bool3" Datatype="Bool" /> </Section> </Sections> </Member> </Section> </Sections> </Member> <Member Name="int7" Datatype="Int" Remanence="NonRetain" Accessibility="Public"> <AttributeList> <BooleanAttribute Name="ExternalAccessible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalVisible" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="ExternalWritable" SystemDefined="true">true</BooleanAttribute> <BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute> </AttributeList> </Member> </Section> </Sections> </Interface> </Document>
原代码(仅提取顶层Member)
string path = ("C:\\Users\\"); XDocument doc = XDocument.Load(path + "File.xml"); XNamespace ns = "http://www.siemens.com/automation/Openness/SW/Interface/v4"; XName name = ns + "Member"; var memb = doc .Root.DescendantsUntil(e => e.Name == name) .Select(e => (Parent: e, Children: e.DescendantsUntil(c => c.Name == name).ToList())) //.Where(i => i.Children.Count > 0); // Uncomment to filter out <Member> elements with no child members. .ToList();
解决方案:提取所有层级的Member
要覆盖所有嵌套层级的<Member>元素,只需先通过Descendants(memberName)遍历整个XML树获取所有<Member>节点,再对每个节点用DescendantsUntil()提取其直接子Member即可。修改后的代码如下:
string path = @"C:\Users\"; XDocument doc = XDocument.Load(path + "File.xml"); XNamespace ns = "http://www.siemens.com/automation/Openness/SW/Interface/v4"; XName memberName = ns + "Member"; // 获取所有层级的Member元素,每个元素包含自身和它的直接子Member集合 var allMembers = doc .Descendants(memberName) .Select(member => ( Parent: member, Children: member.DescendantsUntil(child => child.Name == memberName).ToList() )) .ToList();
关键说明
doc.Descendants(memberName):遍历整个XML文档,返回所有层级的<Member>元素,包括嵌套在其他Member内部的节点。member.DescendantsUntil(child => child.Name == memberName):对每个Member节点,提取其下一层级的直接子Member(不会深入到子Member的子节点)。- 如果需要过滤掉没有子Member的节点,只需取消注释
.Where(i => i.Children.Count > 0)即可。
内容的提问来源于stack exchange,提问作者fabrizio scarpetta
相关产品推荐
相关产品推荐

