XDocument.Descendants无法区分父子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" /> </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>
原有参考代码(获取含Bool的Datatype属性)
XNamespace ns = "http://www.siemens.com/automation/Openness/SW/Interface/v4"; var memb = doc.Descendants(ns + "Member") .Select(f => f.Attribute("Datatype")) .Where(n => n.Value.Contains("Bool")) .ToList(); memb.ForEach(i => Console.WriteLine("{0}\t", i));
需求实现代码
1. 判断Member是否为复合数据类型(包含子Member)
通过检查Member节点下是否存在Sections/Section/Member结构来判断是否为复合类型:
XNamespace ns = "http://www.siemens.com/automation/Openness/SW/Interface/v4"; // 获取Static节下的所有父级Member var parentMembers = doc.Descendants(ns + "Section") .Where(s => s.Attribute("Name")?.Value == "Static") .Elements(ns + "Member"); // 遍历判断每个父Member是否含子元素 foreach (var parent in parentMembers) { bool isComplexType = parent.Elements(ns + "Sections") .Elements(ns + "Section") .Elements(ns + "Member") .Any(); Console.WriteLine($"Member [{parent.Attribute("Name").Value}] 是复合类型: {isComplexType}"); }
2. 提取指定父元素的所有子Member
以示例中Name="3bool1"的父元素为例,提取其子元素:
// 定位目标父Member var targetParent = parentMembers.FirstOrDefault(p => p.Attribute("Name").Value == "3bool1"); if (targetParent != null) { // 提取所有子Member var childMembers = targetParent.Elements(ns + "Sections") .Elements(ns + "Section") .Elements(ns + "Member") .ToList(); Console.WriteLine("\n目标父元素的子元素列表:"); foreach (var child in childMembers) { Console.WriteLine($"Name: {child.Attribute("Name").Value}, Datatype: {child.Attribute("Datatype").Value}"); } }
内容的提问来源于stack exchange,提问作者fabrizio scarpetta
相关产品推荐
相关产品推荐

