c# - modificar - LINQ para leer XML
linq to xml c# ejemplos (5)
Aquí hay un par de ejemplos completos de trabajo que se basan en los ejemplos de @bendewey y @dommer. Necesitaba ajustar cada uno un poco para que funcionara, pero en caso de que otro novato LINQ esté buscando ejemplos de trabajo, aquí tiene:
//bendewey''s example using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ1
{
static void Main( )
{
//Load xml
XDocument xdoc = XDocument.Load(@"c://data.xml"); //you''ll have to edit your path
//Run query
var lv1s = from lv1 in xdoc.Descendants("level1")
select new
{
Header = lv1.Attribute("name").Value,
Children = lv1.Descendants("level2")
};
StringBuilder result = new StringBuilder(); //had to add this to make the result work
//Loop through results
foreach (var lv1 in lv1s)
{
result.AppendLine(" " + lv1.Header);
foreach(var lv2 in lv1.Children)
result.AppendLine(" " + lv2.Attribute("name").Value);
}
Console.WriteLine(result.ToString()); //added this so you could see the output on the console
}
}
Y después:
//Dommer''s example, using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ
{
static void Main( )
{
XElement rootElement = XElement.Load(@"c://data.xml"); //you''ll have to edit your path
Console.WriteLine(GetOutline(0, rootElement));
}
static private string GetOutline(int indentLevel, XElement element)
{
StringBuilder result = new StringBuilder();
if (element.Attribute("name") != null)
{
result = result.AppendLine(new string('' '', indentLevel * 2) + element.Attribute("name").Value);
}
foreach (XElement childElement in element.Elements())
{
result.Append(GetOutline(indentLevel + 1, childElement));
}
return result.ToString();
}
}
Ambos compilan y trabajan en VS2010 utilizando csc.exe versión 4.0.30319.1 y dan el mismo resultado exacto. Esperemos que estos ayuden a alguien más que esté buscando ejemplos de código de trabajo.
EDITAR: agregué el ejemplo de @eglasius también desde que me fue útil:
//@eglasius example, still using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ2
{
static void Main( )
{
StringBuilder result = new StringBuilder(); //needed for result below
XDocument xdoc = XDocument.Load(@"c://deg//data.xml"); //you''ll have to edit your path
var lv1s = xdoc.Root.Descendants("level1");
var lvs = lv1s.SelectMany(l=>
new string[]{ l.Attribute("name").Value }
.Union(
l.Descendants("level2")
.Select(l2=>" " + l2.Attribute("name").Value)
)
);
foreach (var lv in lvs)
{
result.AppendLine(lv);
}
Console.WriteLine(result);//added this so you could see the result
}
}
Tengo este archivo XML
<root>
<level1 name="A">
<level2 name="A1" />
<level2 name="A2" />
</level1>
<level1 name="B">
<level2 name="B1" />
<level2 name="B2" />
</level1>
<level1 name="C" />
</root>
¿Podría alguien darme un código de C # utilizando LINQ, la forma más sencilla de imprimir este resultado?
(Tenga en cuenta el espacio adicional si se trata de un nodo de nivel 2)
A
A1
A2
B
B1
B2
C
Actualmente obtuve este código
XDocument xdoc = XDocument.Load("data.xml"));
var lv1s = from lv1 in xdoc.Descendants("level1")
select lv1.Attribute("name").Value;
foreach (var lv1 in lv1s)
{
result.AppendLine(lv1);
var lv2s = from lv2 in xdoc...???
}
O bien, si desea un enfoque más general, es decir, anidando hasta "levelN":
void Main()
{
XElement rootElement = XElement.Load(@"c:/events/test.xml");
Console.WriteLine(GetOutline(0, rootElement));
}
private string GetOutline(int indentLevel, XElement element)
{
StringBuilder result = new StringBuilder();
if (element.Attribute("name") != null)
{
result = result.AppendLine(new string('' '', indentLevel * 2) + element.Attribute("name").Value);
}
foreach (XElement childElement in element.Elements())
{
result.Append(GetOutline(indentLevel + 1, childElement));
}
return result.ToString();
}
Prueba esto.
void Main()
{
StringBuilder result = new StringBuilder();
//Load xml
XDocument xdoc = XDocument.Load("data.xml");
//Run query
var lv1s = from lv1 in xdoc.Descendants("level1")
select new {
Header = lv1.Attribute("name").Value,
Children = lv1.Descendants("level2")
};
//Loop through results
foreach (var lv1 in lv1s){
result.AppendLine(lv1.Header);
foreach(var lv2 in lv1.Children)
result.AppendLine(" " + lv2.Attribute("name").Value);
}
Console.WriteLine(result);
}
Un par de antiguos bucles foreach
proporcionan una solución limpia:
foreach (XElement level1Element in XElement.Load("data.xml").Elements("level1"))
{
result.AppendLine(level1Element.Attribute("name").Value);
foreach (XElement level2Element in level1Element.Elements("level2"))
{
result.AppendLine(" " + level2Element.Attribute("name").Value);
}
}
XDocument xdoc = XDocument.Load("data.xml");
var lv1s = xdoc.Root.Descendants("level1");
var lvs = lv1s.SelectMany(l=>
new string[]{ l.Attribute("name").Value }
.Union(
l.Descendants("level2")
.Select(l2=>" " + l2.Attribute("name").Value)
)
);
foreach (var lv in lvs)
{
result.AppendLine(lv);
}
PD. Debes usar .Root en cualquiera de estas versiones.