2008-11-14 9 views
10

Soy nuevo en .net y C#, así que quiero asegurarme de estar usando la herramienta adecuada para el trabajo.Caminando un árbol XML en C#

El XML que estoy recibiendo es una descripción de un árbol de directorios en otra máquina, por lo que abarca muchos niveles. Lo que necesito hacer ahora es tomar el XML y crear una estructura de objetos (clases personalizadas) y rellenarlos con información de la entrada XML, como Archivo, Carpeta, Etiquetas, Propiedad ...

La estructura del árbol de esta entrada XML lo hace, en mi opinión, un candidato principal para usar la recursividad para caminar por el árbol.

¿Hay alguna otra manera de hacerlo en .net 3.5?

He mirado en XmlReaders, pero parecen estar caminando el árbol de una forma lineal, no es realmente lo que estoy buscando ...

El XML que estoy recibiendo es parte de un tercero api partido, por lo que está fuera de mi control, y puede cambiar en el futuro.

He examinado la deserialización, pero sus deficiencias (la implementación de la caja negra, la necesidad de declarar a los miembros como pública, lenta, solo funciona para objetos simples ...) también la elimina de la lista.

Gracias por su aportación al respecto.

+0

Hice una pregunta similar, siga el enlace para ver una buena discusión: http://stackoverflow.com/questions/9371541/how-to-create-a-collection-from-list-of-strings-that -represents-a-directory-stru – geekzster

Respuesta

1

Cargue su XML en un XMLDocument. A continuación, puede recorrer el DOM de XMLDocuments mediante la recursión.

Es posible que también desee buscar en el patrón de método de fábrica para crear sus clases, sería muy útil aquí.

2

XmlReader no es una API particularmente amigable. Si puede usar .NET 3.5, entonces cargar en LINQ a XML es su mejor opción. Podría usar fácilmente la recursión con eso.

De lo contrario, XmlDocument todavía lo haría ... solo un poco menos gratamente.

22

Utilizaría las clases XLINQ en System.Xml.Linq (este es el espacio de nombres y el conjunto al que deberá hacer referencia). Cargar el XML en y XDocument:

XDocument doc = XDocument.Parse(someString); 

A continuación, puede utilizar la repetición o un bucle de pseudo-recursión para iterar sobre los nodos secundarios. Usted puede elegir Usted nodos secundarios como:

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

Las variables directoryElements y fileElements será tipos IEnumerable, lo que significa que puede utilizar algo así como un foreach para recorrer todos los elementos. Una manera de construir elementos le sería algo como esto:

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

En el ejemplo, MyFileType es un tipo que ha creado para representar los archivos. Esto es un poco de un ataque de fuerza bruta, pero hará el trabajo.

Si desea utilizar XPath, necesitará usando System.Xml.XPath.


Una nota sobre System.XML vs System.Xml.Linq

Hay una serie de clases XML que han estado en .Net desde los 1,0 días. Estos viven (principalmente) en System.Xml. En .Net 3.5, se lanzó un maravilloso y nuevo conjunto de clases XML en System.Xml.Linq. No puedo enfatizar demasiado sobre lo mucho mejor que son para trabajar con las clases anteriores en System.Xml. Los recomendaría a cualquier programador de .Net y especialmente a alguien que acaba de entrar en .Net/C#.

+1

+1 para enfatizar la diferencia entre System.Xml y System.Xml.Linq. –

2

Este es un problema que es muy adecuado para la recursividad.

Para elaborar un poco más en lo que otro cartel, dijo, tendrá que empezar por cargar el XML en un System.Xml.XmlDocument , (usando LoadXml o de carga).

Puede acceder a la raíz del árbol mediante el XmlDocument.DocumentElement propiedad , y acceder a los hijos de cada nodo utilizando la propiedad ChildNodes. Los nodos secundarios devuelven una colección, y cuando la colección es de tamaño 0, sabrá que habrá alcanzado su caso base.

El uso de LINQ también es una buena opción, pero no puedo profundizar en esta solución, porque en realidad no soy un experto en LINQ.

Como mencionó Jon, XmlReader no es muy amigable. Si termina teniendo problemas de rendimiento, es posible que desee examinarlo, pero si solo desea hacer el trabajo, vaya con XmlDocument/ChildNodes utilizando recursion.