[英]Converting an awkward xml document structure into a friendly one
Okay, so I have an auto-generated xml file which represents a certain folder structure in a library: 好的,所以我有一个自动生成的xml文件,它表示库中的某个文件夹结构:
<Folder>
<Name>One</Name>
<OutlineLevel>0</OutlineLevel>
</Folder>
<Folder>
<Name>Two</Name>
<OutlineLevel>1</OutlineLevel>
</Folder>
<Folder>
<Name>Three</Name>
<OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
<Name>Four</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Five</Name>
<OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
<Name>Six</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Seven</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Eight</Name>
<OutlineLevel>1</OutlineLevel>
</Folder>
However, I need it to look more human-friendly and less awkward in a following structure: 但是,我需要它在以下结构中看起来更人性化且不尴尬:
<Folder Name="One">
<Folder Name="Two">
<Folder Name="Three">
<Folder Name="Four"></Folder>
</Folder>
<Folder Name="Five">
<Folder Name="Six"></Folder>
<Folder Name="Seven"></Folder>
</Folder>
</Folder>
<Folder Name="Eight"></Folder>
</Folder>
I have been looking at it for quite a while already and I am lacking any ideas as to how to wrap it into a method. 我已经看了很长时间了,而且我对如何将其包装到方法中一无所知。 Any suggestions would be highly appreciated. 任何建议将不胜感激。
So far I have been successfull with putting it into objects of my class, which looks like this: 到目前为止,我已经成功地将其放入类的对象中,如下所示:
class MyFolder
{
private List<MyFolder> _folders;
public List<MyFolder> Folders
{
get
{ if (_folders == null)
{ _folders = new List<MyFolder>(); }
return _folders; }
set { _folders = value; }
}
public string Name { get; set; }
}
Don't know if this leads me anywhere to be honest, I now have a MyFolder which has MyFolders which have other MyFolders etc, hopefully this makes sense. 不知道这是否使我无话可说,我现在有一个MyFolder,其中有MyFolders和其他MyFolders等,希望这是有道理的。
I've made a console app. 我做了一个控制台应用程序。 It yields what you need. 它产生您所需要的。 I have wrapped your XML into the FolderTree element just to make parsing easy. 我将您的XML包装到FolderTree元素中只是为了使解析变得容易。
static void Main(string[] args)
{
var xml = @"<FolderTree>
<Folder>
<Name>One</Name>
<OutlineLevel>0</OutlineLevel>
</Folder>
<Folder>
<Name>Two</Name>
<OutlineLevel>1</OutlineLevel>
</Folder>
<Folder>
<Name>Three</Name>
<OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
<Name>Four</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Five</Name>
<OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
<Name>Six</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Seven</Name>
<OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
<Name>Eight</Name>
<OutlineLevel>1</OutlineLevel>
</Folder>
</FolderTree>
";
var root = XElement.Parse(xml);
var elements = root.Elements().ToList();
var rootFolderString = GetItemsAtLevel(new Queue<XElement>(elements), 0).First().ToString();
}
private static void TransformElement(XElement folder)
{
folder.Element("OutlineLevel").Remove();
var nameElement = folder.Element("Name");
nameElement.Remove();
folder.Add(new XAttribute(nameElement.Name, nameElement.Value));
}
private static IEnumerable<XElement> GetItemsAtLevel(Queue<XElement> elements, int level)
{
while (elements.Any())
{
var parent = elements.Dequeue();
var children = new Queue<XElement>();
while (elements.Any() && (int)elements.Peek().Element("OutlineLevel") > level)
{
children.Enqueue(elements.Dequeue());
}
if (children.Any())
{
var subtree = GetItemsAtLevel(children, level + 1);
parent.Add(subtree);
}
TransformElement(parent);
yield return parent;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.