Martin Lauritsen
Martin Lauritsen

Reputation: 23

Linq to xml foreach not working

Hi i have problems getting my foreach to work. It only picks one node, in my simpel linq query. i actly dont no what the problem is, because i usede to be using Xmldocument and xmlnodelist. But i really want to learn do it using Linq, i cannot find anything on google why its not working, i allso tryede the expmales on these links.

http://www.dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples

Simple LINQ to XML is not working

https://forums.asp.net/t/1378244.aspx?Linq+to+XML+query+how+to+get+all+elements+but+excluding+some+

http://www.c-sharpcorner.com/UploadFile/de41d6/learning-linq-made-easy-linq-to-xml-tutorial-3/

Both these examples only return, one xml node.

XElement ele = XElement.Load(filePath);
String aXmlString = ele.ToString(SaveOptions.DisableFormatting) + ele.Value;

foreach (XElement xNode in ele.Descendants("lakeringsdel"))
{
    //litTest.Text = xNode.Element("lakeringsMetode").Value;

    strData = "<table style='width:100%;' >"
         + "<tr>"
         + "<th>Nr.</th>"
         + "<th>Arbejdsbeskrivelse/Omfang</th>"
         + "<th>Metode</th>"
         + "<th>Ae</th>"
         + "</tr>"
         + "<tr>"
         + "<td>" + xNode.Element("ledenr").Value + "</td>"
         + "<td>" + xNode.Element("lakeringsDel").Value + "</td> "
         + "<td>" + xNode.Element("lakeringsMetode").Value + "</td> "
         + "<td>" + xNode.Element("arbejdsEnheder").Value + "</td> "
         + "</tr>"
         +
         "</table>";
}

next example

var test = "";
var q = from c in ele.Descendants("lakeringsdel")
        select c.Element("lakeringsDel").Value;

foreach (string item in q)
{
    test = item;
}

My xml document

<lakRapportDetaljer>
     <aePrTime>10</aePrTime>
     <fabrikatModelTekst>FORD FOCUS (CEW)</fabrikatModelTekst>
     <kilometerStand>28205</kilometerStand>
     <lakArbejde>2745.0</lakArbejde>
     <lakIaltTotal>3610.05</lakIaltTotal>
     <lakIndex>134</lakIndex>
     <lakMaterialer>865.05</lakMaterialer>
     <lakTimepris>450.0</lakTimepris>
     <lakeringsMetode>2-LAGS METALLIC</lakeringsMetode>
     <lakeringsMetode>DØRGREB LEVERES LAKE</lakeringsMetode>
     <lakeringsdel>
        <arbejdsEnheder>10.0</arbejdsEnheder>
        <lakeringsDel>KOFANGER H B</lakeringsDel>
        <lakeringsMetode>REPARATION LAK.PLAST</lakeringsMetode>
        <ledenr>2584</ledenr>
     </lakeringsdel>
     <lakeringsdel>
        <arbejdsEnheder>15.0</arbejdsEnheder>
        <lakeringsDel>BAGSKÆRM HØJRE</lakeringsDel>
        <lakeringsMetode>REP.LAK. &amp;lt;50%, METAL</lakeringsMetode>
        <ledenr>3482</ledenr>
     </lakeringsdel>
     <lakeringsdel>
        <arbejdsEnheder>5.0</arbejdsEnheder>
        <lakeringsDel>SPECIALAFDÆKNING</lakeringsDel>
        <lakeringsMetode>OVERFLADE LAKERING</lakeringsMetode>
        <ledenr>1000</ledenr>
     </lakeringsdel>
     <miljoeLakMaterialerProcent>6</miljoeLakMaterialerProcent>
</lakRapportDetaljer>

Upvotes: 0

Views: 1835

Answers (2)

Xavave
Xavave

Reputation: 695

I've tested your code,but I can't see any problem: it returns three nodes: xml example

if you want to select all elements inside the 3 Xelement nodes "lakeringsdel", you could do :

  var q = from c in ele.Descendants("lakeringsdel")
                select c;

        foreach (XElement item in q)
        {
            test = item.Value;
        }

which gives : xml example 2

or directly:

  var q = ele.Descendants("lakeringsdel");


        foreach (XElement item in q)
        {
            test = item.Value;
        }

which gives the same result

or in 1 line:

ele.Descendants("lakeringsdel").ToList().ForEach(elem=>test =elem.Value);

but as said Reniuz in comment : you store only the last result in your "test" variable

if you want to store all results you could do:

List<string> test = new List<string>();
var q = from c in ele.Descendants("lakeringsdel")
                select c.Element("lakeringsDel").Value;

        foreach (string item in q)
        {
            test.Add(item);
        }

or in 1 line:

 test.AddRange(q);

Upvotes: 1

Mighty Badaboom
Mighty Badaboom

Reputation: 6155

In both examples you set the output strData and test every time you loop through your items. That results in handling nly the last item in your list.

Assuming you want to show a table with the results on your homepage you should change your first example to this

XElement ele = XElement.Load(filePath);
String aXmlString = ele.ToString(SaveOptions.DisableFormatting) + ele.Value;

strData = "<table style='width:100%;' >"
         + "<tr>"
         + "<th>Nr.</th>"
         + "<th>Arbejdsbeskrivelse/Omfang</th>"
         + "<th>Metode</th>"
         + "<th>Ae</th>"
         + "</tr>"

foreach (XElement xNode in ele.Descendants("lakeringsdel"))
{
    //litTest.Text = xNode.Element("lakeringsMetode").Value;

    strData += "<tr>"
         + "<td>" + xNode.Element("ledenr").Value + "</td>"
         + "<td>" + xNode.Element("lakeringsDel").Value + "</td> "
         + "<td>" + xNode.Element("lakeringsMetode").Value + "</td> "
         + "<td>" + xNode.Element("arbejdsEnheder").Value + "</td> "
         + "</tr>";         
}

strData += "</table>";

I would recommend using a StringBuilder to build the string instead of +; whcih could look like this example.

StringBuilder strData = new StringBuilder("<table style='width:100%;'>");
strData.AppendLine("<tr>");
strData.AppendLine("<th>Nr.</th>");

Upvotes: 1

Related Questions