【问题标题】:How to read a specified xml node value using LINQ?如何使用 LINQ 读取指定的 xml 节点值?
【发布时间】:2013-12-09 17:31:18
【问题描述】:

当我指定 VM 名称值时,我想从附加的 xml 文件中读取浏览器和语言值。我尝试多次运行以下方法,但我不断收到错误。任何人都可以建议我的代码修复或更好的方法来获得我想要的东西吗? 非常感谢。 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>

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

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

感谢。

【问题讨论】:

  • 更具体 - 您遇到了什么错误?谢谢。

标签: c# linq xml-parsing


【解决方案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();

    }

【讨论】:

  • 太棒了,谢谢 Shujaat。我确实包含了根目录,但出于某种原因,它没有显示出来。我使用了您的代码,它现在按预期工作。再次感谢。
【解决方案2】:

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

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

【讨论】:

  • 非常感谢您的建议,但我宁愿坚持我所展示的方式,而不是阅读整个 XML 文件。我认为问题出在我的 LINQ 代码中,我不是正确调用某事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
相关资源
最近更新 更多