1

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.

1
  • Be more specific - what errors are you getting? Thanks. Commented Dec 9, 2013 at 17:34

2 Answers 2

1

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();

    }
Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic, thanks Shujaat. I did have the root included but some some reason, it wasn't displayed. I used your code and it now works as expected. Thanks again.
1

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;                
    }                
}

1 Comment

Thanks very much for your suggestion but I'd rather stick with the way I've shown instead of reading the entire XML file in. I think the problem is in my LINQ code, I'm not calling something correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.