C# 在列表中递归读取XML树结构<;T>;有儿童名单<;T>;
我有这样一个XML:C# 在列表中递归读取XML树结构<;T>;有儿童名单<;T>;,c#,recursion,tree,linq-to-xml,C#,Recursion,Tree,Linq To Xml,我有这样一个XML: Unit.Convert(XDocument.Parse(xml).Root.Elements()) 我有一个属性名为的成员类 如何使用最新的.NET技术将每个单元及其子单元读入多个泛型List,这些泛型List可以以递归方式再次具有子单元List <Root> <Units Name="Test1"> <Unit Name="Test11" /> <Unit Name="Test12"> &
Unit.Convert(XDocument.Parse(xml).Root.Elements())
我有一个属性名为的成员类
如何使用最新的.NET技术将每个单元及其子单元读入多个泛型List
,这些泛型List
可以以递归方式再次具有子单元List
<Root>
<Units Name="Test1">
<Unit Name="Test11" />
<Unit Name="Test12">
<Unit Name="Test21" />
<Unit Name="Test22" />
<Unit Name="Test23">
<Unit Name="Test31" />
<Unit Name="Test32" />
<Unit Name="Test33" />
</Unit>
<Unit Name="Test24" />
</Unit>
</Units>
<Units Name="Test2" />
<!-- ... -->
<Units Name="Test3" />
<!-- ... -->
<Units Name="Test4" />
</Root>
为什么不实现一个存储单元的树呢。这将比列表更简单、更自然 请查看使用LinkedList的良好实现 看
public List<Unit> LoadAllUnits(XMLNode rootNode){
List<Unit> allUnits = new List<Unit>();
foreach(var childNode in rootNode.ChildNodes){
allUnits.Add(LoadAllSubUnits(childNode);
}
return allUnits;
}
private Unit LoadAllSubUnits(XMLNode node){
Unit u = GetUnitFromCurrentNode(node); // Converts current node into Unit object
if(root.HasChildNode){
foreach(var childNode in node.ChildNodes){
u.ChildUnits.Add(LoadAllSubUnits(childNode);
}
}
return u;
}
公共列表加载单元(XMLNode rootNode){
List allUnits=新列表();
foreach(rootNode.ChildNodes中的var childNode){
Add(LoadAllSubUnits(childNode));
}
归还冲积物;
}
私有单元LoadAllSubUnits(XMLNode节点){
Unit u=GetUnitFromCurrentNode(node);//将当前节点转换为Unit对象
if(root.HasChildNode){
foreach(node.ChildNodes中的var childNode){
u、 Add(LoadAllSubUnits(childNode));
}
}
返回u;
}
挑战在于将其编写为1个LINQ查询,但我无法理解。LINQ不容易/不适合递归
我会草拟一个解决方案,我不会写出来:
- 将Xml读入XDocument(或XmlDocument)
- 定义
类单元{…;…列出子项;}
- 如果需要,定义单位和根类。我将在这里展平该部分
- 获取所有单位标记的平面列表,
var units=doc.substands(“单位”);
- 迭代这些元素,我假设父节点总是位于嵌套单元之前
- 在
var Lookup=newdictionary()中查找每个节点的父节点;
- 如果找到父节点,请将当前节点(新单元)添加到其子节点
- 否则,将其添加到顶级列表中
- 将新单位和元素添加到字典中
- 仅在创建列表时才需要查找字典
public class Unit
{
public string Name { get; set; }
public List<Unit> Children { get; set; }
}
class Program
{
public static void Main()
{
XDocument doc = XDocument.Load("test.xml");
List<Unit> units = LoadUnits(doc.Descendants("Units").Elements("Unit"));
}
public static List<Unit> LoadUnits(IEnumerable<XElement> units)
{
return units.Select( x=> new Unit()
{ Name = x.Attribute("Name").Value,
Children = LoadUnits(x.Elements("Unit"))
}).ToList();
}
}
公共类单元
{
公共字符串名称{get;set;}
公共列表子项{get;set;}
}
班级计划
{
公共静态void Main()
{
XDocument doc=XDocument.Load(“test.xml”);
列表单位=装载单位(文件子体(“单位”)。元素(“单位”);
}
公共静态列表加载单元(IEnumerable units)
{
返回单位。选择(x=>newunit()
{Name=x.Attribute(“Name”).Value,
子项=荷载单位(x.Elements(“单位”))
}).ToList();
}
}
-我必须使用列表和…列表及其所有子列表必须作为分层数据读取到关系sql数据库中。在这种情况下,使用递归将所有子节点放入一个列表中。我将更新答案。我会认为这是一个尽可能简单的递归实现…@christoba遍历XDoc/XmlDoc有点笨拙。但这是可能的。我建议在回答中用字典替换它。很优雅,但我会将这些转换方法保留在类之外。@BrokenGlass如何从这个层次结构数据中获取顶级单位?
public class Unit
{
public string Name { get; set; }
public List<Unit> Children { get; set; }
}
class Program
{
public static void Main()
{
XDocument doc = XDocument.Load("test.xml");
List<Unit> units = LoadUnits(doc.Descendants("Units").Elements("Unit"));
}
public static List<Unit> LoadUnits(IEnumerable<XElement> units)
{
return units.Select( x=> new Unit()
{ Name = x.Attribute("Name").Value,
Children = LoadUnits(x.Elements("Unit"))
}).ToList();
}
}