2008-11-14 54 views
10

我是.net和c#的新手,所以我想确保我使用正确的工具进行工作。在C中走XML树#

我收到的XML是另一台机器上的目录树的描述,所以它深入了很多级别。我现在需要做的是采用XML并创建一个对象结构(自定义类)并使用来自XML输入的信息填充它们,例如文件,文件夹,标签,属性...

树的结构在我看来,这个XML输入使得它成为使用递归来遍历树的主要候选者。

在.net 3.5中有这样做的不同方式吗?

我已经看了XmlReaders,但他们似乎走在树以线性方式,而不是真的有什么我正在寻找...

的XML我收到是第三部分党的API,这是我无法控制的,并且可能会在期货中发生变化。

我已经研究过反序列化,但它的缺点是(黑盒子的实现,需要声明成员是一个公共的,慢的,只适用于简单的对象...)也将它从列表中取出。

感谢您对此的意见。

+0

我问了一个类似的问题,按照链接看到一个很好的讨论: http://stackoverflow.com/questions/9371541/how-to-create-a-collection-from-list-of-strings-that -represents-a-directory-stru – geekzster 2012-04-03 19:16:08

回答

1

将XML加载到XMLDocument中。然后,您可以使用递归遍历XMLDocuments DOM。

你可能还想看看工厂方法模式来创建你的类,在这里非常有用。

2

XmlReader不是一个特别友好的API。如果你可以使用.NET 3.5,那么加载到LINQ to XML很可能是你最好的选择。你可以很容易地使用递归。

否则,XmlDocument仍然会诀窍...只是不那么愉快。

22

我会在System.Xml.Linq中使用XLINQ类(这是需要引用的名称空间和程序集)。加载XML到和的XDocument:

XDocument doc = XDocument.Parse(someString); 

接下来,你可以使用递归或者伪递归循环遍历子节点。你可以选择你的子节点,如:

//if Directory is tag name of Directory XML 
//Note: Root is just the root XElement of the document 
var directoryElements = doc.Root.Elements("Directory"); 

//you get the idea 
var fileElements = doc.Root.Elements("File"); 

变量directoryElementsfileElements将IEnumerable的类型,这意味着你可以使用像通过所有元素的一个foreach循环。建立你的元素的一种方法是这样的:

List<MyFileType> files = new List<MyFileType>(); 

foreach(XElelement fileElement in fileElements) 
{ 
    files.Add(new MyFileType() 
    {  
     Prop1 = fileElement.Element("Prop1"), //assumes properties are elements 
     Prop2 = fileElement.Element("Prop2"), 
    }); 
} 

在这个例子中,MyFileType是您创建表示文件类型。这是一种暴力攻击,但它会完成工作。

如果你想使用XPath,你将需要使用 System.Xml.XPath。


上的System.Xml的注VS System.Xml.Linq的

有许多自1.0天数一直在净XML类。这些生活(主要)在System.Xml中。在.Net 3.5中,一系列新的XML类在System.Xml.Linq下发布。我不能过分强调它们比System.Xml中的旧类更合适。我强烈建议他们去.Net程序员,尤其是刚刚进入.Net/C#的人。

+1

+1强调System.Xml和System.Xml.Linq之间的区别。 – 2009-12-06 19:17:42

2

这是一个非常适合递归的问题。

更详细地说明一点什么其他的海报说,你会希望通过XML装载到一个System.Xml.XmlDocument,(使用的loadXML负载)开始。

您可以访问根使用XmlDocument.DocumentElement财产树,并通过使用的childNodes属性访问每个节点的孩子。子节点返回一个集合,当Collection的大小为0时,就知道你已经达到了你的基本情况。

使用LINQ也是一个不错的选择,但我无法详细说明这个解决方案,因为我不是一个真正的LINQ专家。

正如乔恩所说,XmlReader不是很友好。如果您最终遇到了perf问题,您可能需要查看它,但如果您只想完成这项工作,请使用递归方式与XmlDocument/ChildNodes一起使用。