Bv202
Bv202

Reputation: 4044

Parse XElement - get element

I currently have an XElement. I use this to print it:

System.Diagnostics.Debug.WriteLine(hostedServices);

Result:

<HostedServices xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <HostedService>
    <Url>url</Url>
    <ServiceName>testcloudservice2</ServiceName>
    <HostedServiceProperties>
      <Description>New cloud service</Description>
      <Location>West Europe</Location>
      <Label>dGVzdGNsb3Vkc2VydmljZTI=</Label>
      <Status>Created</Status>
      <DateCreated>2013-04-02T09:40:27Z</DateCreated>
      <DateLastModified>2013-04-02T09:40:26Z</DateLastModified>
      <ExtendedProperties />
    </HostedServiceProperties>
  </HostedService>
  <HostedService>
    <Url>url</Url>
    <ServiceName>testtesttest123445</ServiceName>
    <HostedServiceProperties>
      <Description>New cloud service</Description>
      <Location>West Europe</Location>
      <Label>dGVzdHRlc3R0ZXN0MTIzNDQ1</Label>
      <Status>Created</Status>
      <DateCreated>2013-04-02T09:30:34Z</DateCreated>
      <DateLastModified>2013-04-02T09:30:34Z</DateLastModified>
      <ExtendedProperties />
    </HostedServiceProperties>
  </HostedService>
</HostedServices>

I'd like to get the ServiceName and Description of each <HostedService>. How can I get these?

Upvotes: 0

Views: 198

Answers (4)

illegal-immigrant
illegal-immigrant

Reputation: 8254

The tricky moment here is that you need to take namespace into account:

XNamespace ns = "http://schemas.microsoft.com/windowsazure";
var serviceNames = element.Descendants(ns + "ServiceName");
var descriptions = element.Descendants(ns + "Description");

var serviceNameValues = serviceNames.Select(x => x.Value);
var descriptionValues = descriptions.Select(x => x.Value);

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236318

You should use XNamespace for selecting elements:

XDocument xdoc = XDocument.Load(path_to_xml);
XNamespace ns = "http://schemas.microsoft.com/windowsazure";
var hostedServices = 
            from s in xdoc.Descendants(ns + "HostedService")
            select new
            {
                ServiceName = (string)s.Element(ns + "ServiceName"),
                Description = (string)s.Element(ns + "HostedServiceProperties")
                                       .Element(ns + "Description")
            };

This will return sequence of anonymous objects with properties ServiceName and Description. Usage:

foreach(var service in hostedServices)
   Debug.WriteLine(service.ServiceName + ": " + service.Description);

Upvotes: 2

Ilya Ivanov
Ilya Ivanov

Reputation: 23646

var xml = XDocument.Parse(s);

XNamespace ns = "http://schemas.microsoft.com/windowsazure";

var descriptions = xml.Descendants(ns + "HostedService")
                      .Select(prop => 
                              new { Description =  prop.Element(ns + "ServiceName").Value, 
                                    ServiceName =  prop.Descendants(ns + "Description").First().Value});

//LINQPad specific print call                
descriptions.Dump();

prints:

Description        ServiceName 
testcloudservice2  New cloud service 
testtesttest123445 New cloud service 

Upvotes: 1

Piotr Zierhoffer
Piotr Zierhoffer

Reputation: 5151

try:

var descriptions = hostedServices.Elements().Select(
    x=> x.Descendants(y=>y.Name=="Description").FirstOrDefault());
var serviceNames = hostedServices.Elements().Select(
    x=> x.Descendants(y=>y.Name=="ServiceName").FirstOrDefault());

If you want them coupled:

var descAndNames = hostedServices.Elements().Select(
    x=> new { Name =  x.Descendants(y=>y.Name=="ServiceName").FirstOrDefault(),
              Description = x.Descendants(y=>y.Name=="Description")
                   .FirstOrDefault()
    });

Upvotes: 0

Related Questions