使用Linq [C#]加载重复命名的XML节点

时间:2009-11-20 18:33:02

标签: c# xml linq-to-xml

我正在开发一个需要能够从XML文件加载对象属性的程序。这些属性可由用户配置,XML对我来说很有意义。

获取以下XML文档。

<?xml version="1.0" encoding="utf-8" ?>

<udpcommands>

  <command name="requser">
    <cvar name="reqchallege" value="false" />
  </command>

  <command name="reqprocs">
    <cvar name="reqchallenge" value="false" />
  </command>

</udpcommands>

我需要能够将上面的cvars中的值加载到属性中。我认为Linq-To-XML会对它有好处( 我正在寻找Linq的应用程序,所以我可以学习它 )。我已经完成了Linq-to-XML查询,根据名称选择了正确的“命令”。我正在阅读MSDN以获取相关帮助。

以下代码片段在一个构造函数中,该构造函数接受参数“string name”,该参数标识要提取的正确XML <command>

我想有一个linq语句,根据节名称将每个<cvar>拉出XML,将所有内容转储到IEnumerable。或者,我正在寻找更好的也许选择。我真的很开心。我只想使用Linq,这样我可以更好地学习它。

    XElement doc = XElement.Load("udpcommands.xml");

    IEnumerable<XElement> a = from el in doc.Elements()
                              where el.FirstAttribute.Value == name
                              select el;

    foreach (var c in a)
    {
        Console.WriteLine(c);
    }

以上代码段将以下内容输出到控制台:

<command name="requser">
  <cvar name="reqchallege" value="false" />
</command>

1 个答案:

答案 0 :(得分:2)

这样的事情应该做:

var result = 
    doc.Elements("command")
    .Single( x => x.Attribute("name").Value == name)
    .Elements("cvar");

这将为您提供IEnumerable<XElement>,其中每个XElement代表指定命令中的cvar

请注意,如果指定的命令不存在,则对Single的调用将导致错误。同样,如果在命令中找不到指定的属性。

编辑根据您的意见,您可以采取以下措施:

// Result will be an XElement, 
// or null if the command with the specified attribute is not found
var result = 
    doc.Elements("command")
    // Note the extra condition below
    .SingleOrDefault( x => x.Attribute("name")!=null && x.Attribute("name").Value == name)

if(result!=null)
{
    // results.Elements() gives IEnumerable<XElement>
    foreach(var cvar in results.Elements("cvar"))
    {
        var cvarName = cvar.Attribute("name").Value;
        var cvarValue = Convert.ToBoolean( cvar.Attribute("value").Value );
    }
}