bearaman
bearaman

Reputation: 1091

How to read a specified xml node value using LINQ?

I'd like to read the browser and language values from the attached xml file when I specify the VM name value. I've tried to run the below method a number of time but I keep getting errors. Can anybody please suggest a fix for my code or a better way to get what I want? Thnaks very much. J.

<?xml version='1.0' encoding='utf-8'?>
<automationSettings>

<!--VM settings on ESX Server-->
<VM name="DE-2K8" language="de" powerOn="true">
    <vmClients>
        <vmClient name="ITXP" language="it"/>
    </vmClients>
    <guest>
        <browser value = "firefox"/>
        <language value = "de"/>
    </guest>
</VM>

<VM name="EN2008" language="en" powerOn="true">
    <vmClients>
        <vmClient name="IT-2K8R2ENT64X" language="it"/>
    </vmClients>
    <guest>
        <browser value = "chrome"/>
        <language value = "en"/>
    </guest>
</VM>

</automationSettings>

Here's the code I'm using to try to get the browser or language values:

public static string ReadVMSettings(string systemName, string section, string name)
{
    try
    {
        systemsFilePath = @"C:\Text.xml";
        Console.WriteLine("Systems.xml path is: " + systemsFilePath);
        XDocument systemXML = XDocument.Load(systemsFilePath);

        var result = from vm in systemXML.Descendants("automationSettings")
                     .Descendants("VM")
                     .Descendants(section)
                     where vm.Attribute("name").Value == systemName
                     select vm.Element(name).Attribute("value").Value;
        return result.First();
    }

    catch (Exception ex)
    {
        Console.WriteLine("ReadVMSettings exception: " + ex.ToString());
        return string.Empty;
    }
}

Call it like this: ReadVMSettings("EN2008", "guest", "language");

Thnaks.

Upvotes: 1

Views: 6225

Answers (2)

shujaat siddiqui
shujaat siddiqui

Reputation: 1587

You are missing the root element in your xml pattern

you Xml Should be like

<?xml version="1.0" encoding="utf-8" ?>
<automationSettings> //missing root element
<VM name="DE-2K8" language="de" powerOn="true">
  <vmClients>
    <vmClient name="ITXP" language="it"/>
  </vmClients>
  <guest>
    <browser value = "firefox"/>
    <language value = "de"/>
  </guest>
</VM>

<VM name="EN2008" language="en" powerOn="true">
  <vmClients>
    <vmClient name="IT-2K8R2ENT64X" language="it"/>
  </vmClients>
  <guest>
    <browser value = "chrome"/>
    <language value = "en"/>
  </guest>
</VM>
</automationSettings> 

Here you go ...

    static void Main(string[] args)
    {
        string value = ReadVMSettings("EN2008", "guest", "browser");
    }

    public static string ReadVMSettings(string systemName, string section, string name)
    {
        string systemsFilePath = @"C:\Text.xml";
        Console.WriteLine("Systems.xml path is: " + systemsFilePath);
        XDocument systemXML = XDocument.Load(systemsFilePath);
        var result = from vm in systemXML.Root.Descendants("VM")
                     where vm.Attribute("name").Value == systemName
                     select vm.Element(section).Element(name).Attribute("value").ToString();
        return result.FirstOrDefault().ToString();

    }

Upvotes: 1

jiverson
jiverson

Reputation: 1234

This should return the language value you are seeking in your example.

string val = SettingFromXML(
    @"<!--VM settings on ESX Server-->                
    <VM name=""DE-2K8"" language=""de"" powerOn=""true"">
        <vmClients>
            <vmClient name=""ITXP"" language=""it""/>
        </vmClients>
        <guest>
            <browser value = ""firefox""/>
            <language value = ""de""/>
        </guest>
    </VM>
    <VM name=""EN2008"" language=""en"" powerOn=""true"">
        <vmClients>
            <vmClient name=""IT-2K8R2ENT64X"" language=""it""/>
        </vmClients>
        <guest>
            <browser value = ""chrome""/>
            <language value = ""en""/>
        </guest>
    </VM>", "EN2008", "guest", "language"
);
MessageBox.Show(val);

public static string SettingFromXML(string xml, string systemName, string section, string name) {
    xml = "<VMSettings>" + xml + "</VMSettings>"; // wrap XML in root node to deal with multiple root node exception
    using (MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(xml))) {
        XDocument xDoc = XDocument.Load(ms);
        return xDoc.Descendants("VMSettings")
                   .Descendants("VM").First(el1 => el1.Attribute("name").Value == systemName)
                   .Descendants().First(el2 => el2.Name == section)
                   .Descendants().First(el3 => el3.Name == name).Attribute("value").Value;                
    }                
}

Upvotes: 1

Related Questions