8

我有一个自定义配置文件。

<Students>
 <student>
   <Detail Name="abc" Class="1st Year">
       <add key="Main" value="web"/>
       <add key="Optional" value="database"/>
   </Detail>
 </student>
</Students>

我通过 IConfigurationHandler 接口实现读取了这个文件。当我阅读 Detail 元素的 childNode 属性时。它将下面的结果返回到 IDE 的即时窗口中。

elem.Attributes.ToObjectArray()

{object[2]}
    [0]: {Attribute, Name="key", Value="Main"}
    [1]: {Attribute, Name="value", Value="web"}

当我尝试在控制台上写

 Console.WriteLine("Value '{0}'",elem.Attributes.ToObjectArray());

它确实返回了我

Value : 'System.Configuration.ConfigXmlAttribute'

elem.Attributes.Item(1)方法给了我名称和值的详细信息,但在这里我需要传递我目前不知道的属性的索引值。

我想通过LINQ 查询获取属性的名称和值,并在控制台上为每个 childNode 属性单独显示如下:

Value : Name="Key" and Value="Main"
        Name="value", Value="web"

我怎样才能做到这一点?

4

4 回答 4

3

您可以使用 Linq Selectstring.Join来获得所需的输出。

string.Join(Environment.NewLine, 
    elem.Attributes.ToObjectArray()
        .Select(a => "Name=" + a.Name + ", Value=" + a.Value)
)
于 2012-05-24T08:06:49.370 回答
3

如果您想使用这个Xml 库,您可以使用以下代码获取所有学生及其详细信息:

XElement root = XElement.Load(file); // or .Parse(string)
var students = root.Elements("student").Select(s => new
{
    Name = s.Get("Detail/Name", string.Empty),
    Class = s.Get("Detail/Class", string.Empty),
    Items = s.GetElements("Detail/add").Select(add => new
    {
        Key = add.Get("key", string.Empty),
        Value = add.Get("value", string.Empty)
    }).ToArray()
}).ToArray();

然后迭代它们使用:

foreach(var student in students)
{
    Console.WriteLine(string.Format("{0}: {1}", student.Name, student.Class));
    foreach(var item in student.Items)
        Console.WriteLine(string.Format("  Key: {0}, Value: {1}", item.Key, item.Value));
}
于 2012-06-14T20:38:29.377 回答
2

正如您在问题中所述,这将获得 Detail 元素的子元素的所有属性。

XDocument x = XDocument.Parse("<Students> <student> <Detail Name=\"abc\" Class=\"1st Year\"> <add key=\"Main\" value=\"web\"/> <add key=\"Optional\" value=\"database\"/> </Detail> </student> </Students>");

var attributes = x.Descendants("Detail")
                  .Elements()
                  .Attributes()
                  .Select(d => new { Name = d.Name, Value = d.Value }).ToArray();

foreach (var attribute in attributes)
{
     Console.WriteLine(string.Format("Name={0}, Value={1}", attribute.Name, attribute.Value));
}
于 2012-06-17T02:06:31.370 回答
0

如果你在写的时候有属性object[],可以通过

var Attributes = new object[]{
    new {Name="key", Value="Main"},
    new {Name="value", Value="web"}
};

那么问题是您有匿名类型,其名称无法轻松提取。

看一下这段代码(你可以将它粘贴到 LinqPad 编辑器窗口的 main() 方法中来执行它):

var linq=from a in Attributes
let s = string.Join(",",a).TrimStart('{').TrimEnd('}').Split(',')
select new 
{
    Value = s[0].Split('=')[1].Trim(),
    Name = s[1].Split('=')[1].Trim()
};
//linq.Dump();

由于您无法访问object[]数组中的变量Attributes的 Name 和 Value 属性,因为编译器对您隐藏了它们,因此这里的诀窍是使用Join(",", a)方法来绕过这个限制。

之后您需要做的就是修剪拆分生成的字符串,最后创建一个具有ValueName属性的新对象。如果您取消注释linq.Dump();,您可以尝试一下。LinqPad 中的行 - 它返回您想要的内容,并且可以通过 Linq 语句查询。

于 2012-06-19T12:22:20.263 回答