0

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>
Mighty Badaboom
  • 6,067
  • 5
  • 34
  • 51
  • 1
    Your string in example code will hold last iteration result. Maybe you want to append it or something. – Renatas M. Jul 18 '17 at 09:48
  • Also you need to escape the values you use to build your string, if ledenr, lakeringsDel, lakeringsMetode or arbejdsEnheder contain a & or < char then your HTML will be invalid. You should also consider the source of the data; the code you have opens you up to a malicious user to inject script into the resulting html (a common source of cross site scripting exploits). You should look at escaping and ideally sanitizing the data you inject into the HTML you are building. Also use a StringBuilder to construct the string its MUCH faster. I think you should also be using Elements (not Descendants). – Sprotty Jul 18 '17 at 09:59
  • Also See https://stackoverflow.com/questions/341872/html-sanitizer-for-net – Sprotty Jul 18 '17 at 10:02
  • lakeringsdel tag does have any innertext so this will return nothing : select c.Element("lakeringsDel").Value; If you remove Value you will get a List. – jdweng Jul 18 '17 at 10:03
  • i will definitely look into it, but this query, will not be visible on html page, im just opening it. Creating and html table in codebehind with the data, and adding the data to and PDF using itextsharp, it all happens in codebehind. – Martin Lauritsen Jul 18 '17 at 14:53

2 Answers2

1

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);
Xavave
  • 645
  • 11
  • 15
1

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>");
Mighty Badaboom
  • 6,067
  • 5
  • 34
  • 51