在 C# 中遍历 XML 树

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/291387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:54:46  来源:igfitidea点击:

Walking an XML tree in C#

c#.netxml

提问by slither

I'm new to .net and c#, so I want to make sure i'm using the right tool for the job.

我是 .net 和 c# 的新手,所以我想确保我使用的是正确的工具来完成这项工作。

The XML i'm receiving is a description of a directory tree on another machine, so it go many levels deep. What I need to do now is to take the XML and create a structure of objects (custom classes) and populate them with info from the XML input, like File, Folder, Tags, Property...

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

The Tree stucture of this XML input makes it, in my mind, a prime candidate for using recursion to walk the tree.

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

Is there a different way of doing this in .net 3.5?

在 .net 3.5 中是否有不同的方法来做到这一点?

I've looked at XmlReaders, but they seem to be walking the tree in a linear fashion, not really what i'm looking for...

我看过 XmlReaders,但它们似乎以线性方式在树上行走,并不是我真正想要的......

The XML i'm receiving is part of a 3rd party api, so is outside my control, and may change in the futures.

我收到的 XML 是第 3 方 api 的一部分,因此不在我的控制范围内,并且可能会在未来发生变化。

I've looked into Deserialization, but it's shortcomings (black box implementation, need to declare members a public, slow, only works for simple objects...) takes it out of the list as well.

我已经研究了反序列化,但它的缺点(黑盒实现,需要将成员声明为公共,速度慢,仅适用于简单对象......)也将其从列表中删除。

Thanks for your input on this.

感谢您对此的意见。

回答by FlySwat

Load your XML into an XMLDocument. You can then walk the XMLDocuments DOM using recursion.

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

You might want to also look into the factory method pattern to create your classes, would be very useful here.

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

回答by Jon Skeet

XmlReader isn't a particularly friendly API. If you can use .NET 3.5, then loading into LINQ to XML is likely to be your best bet. You could easily use recursion with that.

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

Otherwise, XmlDocument would still do the trick... just a bit less pleasantly.

否则,XmlDocument 仍然可以解决问题……只是不太愉快。

回答by Jason Hymanson

I would use the XLINQ classes in System.Xml.Linq (this is the namespace and the assembly you will need to reference). Load the XML into and XDocument:

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

XDocument doc = XDocument.Parse(someString);

Next you can either use recursion or a pseudo-recursion loop to iterate over the child nodes. You can choose you child nodes like:

接下来,您可以使用递归或伪递归循环来迭代子节点。您可以选择子节点,例如:

//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"); 

The variables directoryElementsand fileElementswill be IEnumerable types, which means you can use something like a foreach to loop through all of the elements. One way to build up you elements would be something like this:

变量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"),
    });
}

In the example, MyFileTypeis a type you created to represent files. This is a bit of a brute-force attack, but it will get the job done.

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

If you want to use XPath you will need to usingSystem.Xml.XPath.

如果要使用 XPath,则需要使用System.Xml.XPath。



A Note on System.Xml vs System.Xml.Linq

关于 System.Xml 与 System.Xml.Linq 的说明

There are a number of XML classes that have been in .Net since the 1.0 days. These live (mostly) in System.Xml. In .Net 3.5, a wonderful, new set of XML classes were released under System.Xml.Linq. I cannot over-emphasize how much nicer they are to work with than the old classes in System.Xml. I would highly recommend them to any .Net programmer and especially someone just getting into .Net/C#.

自 1.0 天以来,.Net 中就有许多 XML 类。这些(大部分)存在于 System.Xml 中。在 .Net 3.5 中,在 System.Xml.Linq 下发布了一组精彩的新 XML 类。我不能过分强调它们比 System.Xml 中的旧类好用多少。我会向任何 .Net 程序员,尤其是刚开始使用 .Net/C# 的人强烈推荐它们。

回答by brad

This is a problem which is very suitable for recursion.

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

To elaborate a bit more on what another poster said, you'll want to start by loading the XML into a System.Xml.XmlDocument, (using LoadXmlor Load).

为了详细说明另一张海报所说的内容,您需要首先将 XML 加载到System.Xml.XmlDocument中(使用LoadXmlLoad)。

You can access the root of the tree using the XmlDocument.DocumentElementproperty, and access the children of each node by using the ChildNodes property. Child nodes returns a collection, and when the Collection is of size 0, you know you'll have reached your base case.

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

Using LINQ is also a good option, but I'm unable to elaborate on this solution, cause I'm not really a LINQ expert.

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

As Jon mentioned, XmlReader isn't very friendly. If you end up having perf issues, you might want to look into it, but if you just want to get the job done, go with XmlDocument/ChildNodes using recursion.

正如 Jon 提到的,XmlReader 不是很友好。如果您最终遇到性能问题,您可能需要调查它,但如果您只想完成工作,请使用递归使用 XmlDocument/ChildNodes。