繁体   English   中英

C#使用LINQ to XML读取具有相同名称的多个元素

[英]C# Reading multiple elements with same name using LINQ to XML

有什么更好的办法吗? 我必须同时获取两个属性值。 XML始终仅具有这两个属性。

我的xml:

<Template name="filename.txt">
  <Property name="recordSeparator">\r\n</Property>
  <Property name="fieldCount">16</Property>
</Template>

LINQ:

            var property = from template in xml.Descendants("Template")
                       select new
                                  {
                                      recordDelim = template.Elements("Property").Where(prop => prop.Attribute("name").Value == "recordSeparator")
                                                    .Select(f => new { f.Value }),
                                      fieldCount = template.Elements("Property").Where(prop => prop.Attribute("name").Value == "fieldCount")
                                                    .Select(f => new { f.Value })
                                  };

“更好的方式”取决于您到底要达到什么目标-性能,简单性等?

我想我会创建一个包含您试图从匿名类获得的类的类。

public class Item {
    public String Separator { get; set; }
    public int FieldCount { get; set; }
}

然后将LINQ修改为:

var templates = from template in xml.Descendants("Template")
                let children = template.Elements("Property")
                select new Item() {
                    Separator = children.First(tag=>tag.Attribute("name").Value == "recordSeparator").Value,
                    FieldCount = Int32.Parse(children.First(tag=>tag.Attribute("name").Value == "fieldCount").Value)
                };

List<Item> items = templates.ToList();

请注意,如果您的Template标记不包含两个具有指定属性的Property标记,这将导致NullReference异常。

如果它不是数字,也会在解析FieldCount中的整数时引发异常。

理念:

如果生成的xml是您自己的,并且可以更改其格式,那么为什么不这样做:

<Template>
  <Name>filename.txt</Name>
  <RecordSeparator>\r\n</RecordSeparator>
  <FieldCount>16</FieldCount>
</Template>

它更易于阅读和解析,并且更短一些。

最后,我认为这是我要做的:

上这堂课:

public class Item 
{
   public String FileName { get; set; }
   public String Separator { get; set; }
   public int FieldCount { get; set; }
}

和这个私有方法:

private Item GetItemFromTemplate(XElement node) 
{
    return new Item() {
        FileName = node.Element("Name").Value,
        Separator = node.Element("RecordSeparator").Value,
        FieldCount = Int32.Parse(node.Element("FieldCount").Value)
    }; 
}    

我可以用代码来做:

XDocument doc = XDocument.Load("myfile.txt");

List<Item> items = (from template in doc.Elements("Template")
                   select GetItemFromTemplate(template)).ToList();

这一点效率更高:

var properties =
    from template in xml.Descendants("Template")
    let propertyNodes = template.Elements("Property")
        .Select(arg => new { Name = arg.Attribute("name").Value, Value = arg.Value })
    select
        new
        {
            recordDelim = propertyNodes.Single(arg => arg.Name == "recordSeparator").Value,
            fieldCount = propertyNodes.Single(arg => arg.Name == "fieldCount").Value
        };

如果您始终有一个“ Template节点:

var propertyNodes = xml.XPathSelectElements("/Template/Property")
    .Select(arg => new { Name = arg.Attribute("name").Value, arg.Value })
    .ToList();

var properties =
    new
    {
        recordDelim = propertyNodes.Single(arg => arg.Name == "recordSeparator").Value,
        fieldCount = propertyNodes.Single(arg => arg.Name == "fieldCount").Value
    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM