如何使用LINQ读取指定的xml节点值?

时间:2013-12-09 17:31:18

标签: c# linq xml-parsing

当我指定VM名称值时,我想从附加的xml文件中读取浏览器和语言值。我试过运行下面的方法很多次,但我一直在收到错误。任何人都可以建议修复我的代码或更好的方式来获得我想要的东西吗? 非常狡猾。 学家

<?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>

以下是我用来尝试获取浏览器或语言值的代码:

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

这样称呼它:     ReadVMSettings(“EN2008”,“guest”,“language”);

Thnaks。

2 个答案:

答案 0 :(得分:1)

这应该返回您在示例中寻求的语言值。

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 :(得分:1)

您缺少xml模式中的根元素

你Xml应该像

<?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> 

你去......

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

    }