0

I'm trying to get a List of Styles in the following xml file using xdoc and LINQ.

<?xml version="1.0" encoding="UTF-8"?>
<kml>
  <Document>
    <Style id="style62">
      <IconStyle>
        <Icon>
          <href>http://maps.gstatic.com/mapfiles/ms2/micons/yellow-dot.png</href>
        </Icon>
      </IconStyle>
    </Style>
  </Document>
</kml>

I cannot get my syntax right in order to get the ID="style62" AND also the value within href in the same LINQ select, can anyone help?

var styles = xdoc.Descendants(ns + "Style")
                .Select(s => new
                {
                    //HELP!?!
                    //E.G
                    //
                    //id = s.something  (style62)
                    //href = s.something (url)
                }).ToList();
Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
norbert
  • 335
  • 1
  • 7
  • 19

4 Answers4

4

if you are talking about a kml file like here https://developers.google.com/kml/documentation/KML_Samples.kml then below code should work. The problem here is that every "Style" does not contain "href" tag.

var xDoc = XDocument.Parse(xml);
XNamespace ns = "http://www.opengis.net/kml/2.2";
var items = xDoc.Descendants(ns + "Style")
                .Select(d => 
                {
                   var h = d.Descendants(ns + "href").FirstOrDefault();
                   return new
                   {
                       Id = d.Attribute("id").Value,
                       Href = h == null ? null : h.Value
                   };
                })
                .ToList();

With a simple extension method, you can simplify the query

XNamespace ns = "http://www.opengis.net/kml/2.2";
var items = xDoc.Descendants(ns + "Style")
                .Select(d => new
                {
                   Id = d.Attribute("id").Value,
                   HRef = d.Descendants(ns + "href").FirstOrDefault()
                                                    .IfNotNull(h=>h.Value)
                })
                .ToList();



public static class S_O_Extensions
{
    public static S IfNotNull<T, S>(this T obj,Func<T,S> selector)
    {
        if (obj == null) return default(S);
        return selector(obj);
    }
 }
L.B
  • 114,136
  • 19
  • 178
  • 224
0

Something like this should work:

xdoc.Descendants(ns + "Style")
    .Select(s => new
                 {
                     id = s.Attribute("id").Value,
                     href = s.Element("IconStyle")
                             .Element("Icon")
                             .Element("href")
                             .Value
                 });
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
0

Run this through LinqPad:

XDocument doc = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<kml>" +
  "<Document>" +
    "<Style id=\"style62\">" +
      "<IconStyle>" +
        "<Icon>" +
          "<href>http://maps.gstatic.com/mapfiles/ms2/micons/yellow-dot.png</href>" +
        "</Icon>" +
      "</IconStyle>" +
    "</Style>" +
  "</Document>" +
"</kml>");

var styles = from document in doc.Root.Elements("Document")
            from style in document.Elements("Style")
            where style.Attribute("id").Value == "style62"
            select new 
            {
                StyleElement = style,
                Href = style.Element("IconStyle").Element("Icon").Element("href").Value
            };


styles.Dump();
devlife
  • 15,275
  • 27
  • 77
  • 131
0

you can use linq like

var items = doc.Descendants("field")
           .Where(node => (string)node.Attribute("name") == "Name")
           .Select(node => node.Value.ToString())
           .ToList();
Dhaval Patel
  • 7,471
  • 6
  • 37
  • 70