在我之前的问题中:link https://stackoverflow.com/questions/75957548/xdocument-descendants-cannot-distinguish-between-parent-child-elements,
我学习了如何使用名为“后代直到()”的扩展方法来查找最顶层元素(父元素)及其最顶层后代元素(子元素)。
现在让我们假设有更多的后代(父母、孩子、侄子等..):
<?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>
通过使用 DescendantsUntil() 扩展方法,我可以轻松过滤父级和子级
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();
现在,我如何使用 DescendantsUntil() 来提取 Parent、Children、Nephews 元素,以及一般来说,只要存在另一个嵌套元素,如何提取所有后代?
尝试这样的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication52
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement xSections = doc.Descendants().Where(x => x.Name.LocalName == "Sections").FirstOrDefault();
XNamespace ns = xSections.GetDefaultNamespace();
Sections root = new Sections();
root.ParseSections(xSections, ns);
}
}
public class Sections
{
public List<Section> sections { get; set; }
public void ParseSections(XElement xSections, XNamespace ns)
{
List<XElement> sections = xSections.Elements(ns + "Section").ToList();
foreach (XElement section in sections)
{
if (this.sections == null) this.sections = new List<Section>();
Section childSection = new Section();
this.sections.Add(childSection);
childSection.ParseSection(section, ns);
}
}
}
public class Section
{
public string name { get; set; }
public List<Member> members { get; set; }
public void ParseSection(XElement xSection, XNamespace ns)
{
this.name = (string)xSection.Attribute("Name");
foreach (XElement xMember in xSection.Elements(ns + "Member"))
{
if (this.members == null) this.members = new List<Member>();
Member member = new Member();
this.members.Add(member);
member.ParseMember(xMember, ns);
}
}
}
public class Member
{
public string name { get; set; }
public string remanence { get; set; }
public string accessibility { get; set; }
public Dictionary<string, Boolean> attributes { get; set; }
public Sections sections { get; set; }
public void ParseMember(XElement member, XNamespace ns)
{
this.name = (string)member.Attribute("Name");
this.remanence = (string)member.Attribute("Remanence");
this.accessibility = (string)member.Attribute("Accessibility");
XElement attributeList = member.Element(ns + "AttributeList");
if (attributeList != null)
{
foreach (XElement attribute in attributeList.Descendants(ns + "BooleanAttribute"))
{
if (attributes == null) attributes = new Dictionary<string, bool>();
string attributeName = (string)attribute.Attribute("Name");
Boolean attributeValue = (Boolean)attribute;
attributes.Add(attributeName, attributeValue);
}
}
XElement xSections = member.Element(ns + "Sections");
if (xSections != null)
{
Sections childSections = new Sections();
this.sections = childSections;
childSections.ParseSections(xSections, ns);
}
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)