2010-03-03 19 views
13

Tengo archivos XML fuente que vienen con múltiples elementos raíz y no hay nada que pueda hacer al respecto. ¿Cuál sería la mejor manera de cargar estos fragmentos en un XDocument con un único nodo raíz que pueda crear para tener un documento XML válido?LINQ to XML - Cargar fragmentos XML del archivo

muestra:

<product></product> 
<product></product> 
<product></product> 

debe ser algo como:

<products> 
    <product></product> 
    <product></product> 
    <product></product> 
</products> 

Gracias!

Respuesta

18

He aquí cómo hacerlo con un XmlReader, que es probablemente el más flexible y enfoque más rápido rendimiento:

XmlReaderSettings xrs = new XmlReaderSettings(); 
xrs.ConformanceLevel = ConformanceLevel.Fragment; 

XDocument doc = new XDocument(new XElement("root")); 
XElement root = doc.Descendants().First(); 

using (StreamReader fs = new StreamReader("XmlFile1.xml")) 
using (XmlReader xr = XmlReader.Create(fs, xrs)) 
{ 
    while(xr.Read()) 
    { 
     if (xr.NodeType == XmlNodeType.Element) 
     { 
      root.Add(XElement.Load(xr.ReadSubtree()));     
     } 
    } 
} 
+0

Gracias Robert, esto es exactamente lo que estaba tratando de hacer, pero tuve problemas para usar el lector correctamente, supongo :). Esto también es genial porque puedo agregar otra marca para el nombre del elemento para filtrar algunos elementos que no necesito. –

+0

@Robert Rossney: ¿por qué el cheque "if (xr.NodeType == XmlNodeType.Element)"? –

+1

El método 'Read' puede devolver muchas cosas que no son elementos: secciones CDATA, instrucciones de procesamiento, comentarios, declaraciones XML, referencias a entidades, etc. El código anterior saltará los comentarios (por ejemplo) en lugar de agregarlos al' XDocument', que puede no ser lo que se desea, pero al menos no lanzará una excepción. –

-5

aproximadamente, algo así como.

var newXML= new XElement("products", 
       from x in Xdocuments.parse(originalFile).descendants("product")      
       select new XElement("product",x.value) 
      ); 
+0

Esta seguirá siendo una excepción cuando se hace XDocument.Parse (originalFile) –

+0

carga de hecho, que quería decir, lo hice decir "algo así como"! :) analiza una cadena o carga un archivo; ambos están bien :) –

+0

Load() tampoco funcionará. ¿Has probado esto? –

8

Te dejaré para ponerlo en un campo de cadena, pero básicamente se puede hacer esto:

myDoc=new XmlDocument(); 
myDoc.LoadXml("<products>"+myData+"</products>"); 
+1

No me gusta tener que sacar la cadena del archivo y simplemente colocarla allí sin alguna forma de verificación que sea realmente válida XML. –

+0

para un juego rápido y sucio que es en realidad un buen truco para recordar –