Marcus Borén
Marcus Borén

Reputation: 23

How to get ALL occurrences of an element in a descendants in XML

So I've did something that gets all polygon elements in an XML file and then drawing the polygons, but when I drew them I realized I am missing a lot of polygons elements.

The code I use to get the polygon elements

List<XElement> hs1 = doc.Descendants("signal")
                .Where(x => (x.Element("contactref") != null) && (x.Element("contactref")
                .Attribute("element") != null) && ((string)x.Attribute("name") != "EPD_PWR") && ((string)x.Element("contactref")
                .Attribute("element") == "HS1") && x.Element("polygon") != null)
                .Select(x => x.Element("polygon")).ToList();            .Select(x => x.Element("polygon")).ToList();

Then I do some foreach and stuff to get all the vertex element inside the polygon.

foreach (XElement item in hs1)
            {
                int counter = 0;
                List<string> vx = new List<string>(), vy = new List<string>();

                if (item != null)
                {
                    foreach (XElement vert in item.Elements())
                    {
                        vx.Add(vert.Attribute("x").Value.ToString());
                        vy.Add(vert.Attribute("y").Value.ToString());

                        counter++;
                    }//Foreach
                }//IF
                points = new PointF[counter];
                for (int i = 0; i < vx.Count; i++)
                {
                    points[i].Y = (float.Parse(vx[i].Replace(".", ",")) * 10) / 2;
                    points[i].X = (float.Parse(vy[i].Replace(".", ",")) * 10);
                }//For

This is working fine, but then I realized I am getting only the firsy polygon element in the descendants and not all, because some descendants has more then 1 polygon element in them. i.e.

<signals>
 <signal name="N$1">
  <contactref element="HS1" pad="1"/>
  <polygon width="0.05" layer="1">
   <vertex x="0" y="0"/>
   <vertex x="83" y="0"/>
   ...
  </polygon>
 </signal>
 <signal name="N$2">
  <contactref element="HS1" pad="2"/>
  <polygon width="0.05" layer="1">
   <vertex x="33.638" y="8.084"/>
   <vertex x="33.571" y="7.927"/>
   ...
  </polygon>
  <polygon width="0.05" layer="1">
   <vertex x="21.496" y="23.739"/>
   <vertex x="21.607" y="23.604"/>
  </polygon>
 </signal>
</signals>

So in the example XML above I wanna get ALL "polygon" elements in "signal" but I am only getting the first one with my code.

Where is it going wrong? In my doc.descendants or is it in my foreach loops?

Thanks in advance

Upvotes: 1

Views: 324

Answers (1)

Vasilievski
Vasilievski

Reputation: 863

You should call Elements instead of Element on the last line building hs1.

Taking @Bradley Uffner comment into account, if you want a flat list of polygons, you can replace Select by SelectMany.

List<XElement> hs1 = doc.Descendants("signal")
                .Where(x => (x.Element("contactref") != null) && (x.Element("contactref")
                .Attribute("element") != null) && ((string)x.Attribute("name") != "EPD_PWR") && ((string)x.Element("contactref")
                .Attribute("element") == "HS1") && x.Element("polygon") != null)
                .SelectMany(x => x.Elements("polygon")).ToList(); 

Upvotes: 1

Related Questions