tags:

views:

86

answers:

4

My requirement here is to retrieve the node that matches the hostname (for eg. machine1) and I always get back no results. Please let me know what the problem is?

Thanks for the help in advance!!!

XDocument configXML = XDocument.Load("the below xml");

var q = from s in configXML.Descendants("lcsetting")
    where ((string)s.Element("host") == hostName)                        
    select s;

The actual xml:

<lcsettings>
  <lcsetting env="prod">
    <hosts usagelogpath="">
      <host>machine1</host>
      <host>machine2</host>
      <host>machine3</host>
    </hosts>
  </lcsetting>
  <lcsetting env="qa">
    <hosts usagelogpath="">
      <host>machine4</host>
      <host>machine5</host>
      <host>machine6</host>
    </hosts>
  </lcsetting>
  <lcsetting env="test">
    <hosts usagelogpath="">
      <host>machine7</host>
      <host>machine8</host>
      <host>machine9</host>
    </hosts>
  </lcsetting>
</lcsettings>
+4  A: 

You're looking for a host element directly under an lcsetting - that doesn't occur because there's always a hosts element between the two in the hierarchy. You're also using Element instead of Elements, which means only the first element with the right name will be returned.

You could use Descendants again instead of Element... but you'll need to change the condition. Something like:

var q = from s in configXML.Descendants("lcsetting")
        where s.Descendants("host").Any(host => host.Value == hostName)
        select s;

Alternatively, you could make your query find host elements and then take the grandparent element in each case:

var q = from host in configXML.Descendants("host")
        where host.Value == hostName
        select host.Parent.Parent;

(This assumes a host element will only occur once per lcsetting; if that's not the case, you can add a call to Distinct.)

Jon Skeet
Thanks for your reply. Also, Is it possible to retrieve a default lcsetting element (say "qa") if the query returns no results.
Ganesha
+1  A: 

"host" is not a child of "lcsetting".

dommer
+1  A: 

That is because you have a <hosts> tag immedieately below your lcsetting, that contains your <host> tags. <host> is not an immedieate child of <lcsetting>.

This query will work:

var q = from s in configXML.Descendants("lcsetting").SelectMany(lcSetting => lcSetting.Descendants("host"))
        where s.Name == "host" && s.Value == hostName
        select s;
driis
+1  A: 

You're selecting the descendants lcsetting but then attempting to check the element host which is two levels below it. The Element() function references only child elements 1 level deep. I'd recommend changing this to:

XDocument configXML = XDocument.Load("the below xml");
var q = from s in configXML.Descendants("lcsetting") 
        where s.Descendants("host").SingleOrDefault(e => e.Value == hostname) != null
        select s;
James Alexander