[英]C# Reading multiple elements with same name using LINQ to XML
Is there any better way doing this? 有什么更好的办法吗? I have to get both property values.
我必须同时获取两个属性值。 XML always has only these 2 properties.
XML始终仅具有这两个属性。
My xml: 我的xml:
<Template name="filename.txt">
<Property name="recordSeparator">\r\n</Property>
<Property name="fieldCount">16</Property>
</Template>
Linq: 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 })
};
"Better way" depends on what exactly are you trying to achieve - performance, simplicity, etc.? “更好的方式”取决于您到底要达到什么目标-性能,简单性等?
I guess I would create a class that contains what you are trying to get with anonymous classes. 我想我会创建一个包含您试图从匿名类获得的类的类。
public class Item {
public String Separator { get; set; }
public int FieldCount { get; set; }
}
and then I would modify the LINQ to: 然后将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();
Note that this will cause NullReference
exception in case your Template tag does not contain two Property tags, each with specified attributes. 请注意,如果您的Template标记不包含两个具有指定属性的Property标记,这将导致
NullReference
异常。
Also it will throw an exception in parsing the integer from a FieldCount if it's not a number. 如果它不是数字,也会在解析FieldCount中的整数时引发异常。
Idea: 理念:
If the xml generated is your own, and you can change it's format, why not do something like: 如果生成的xml是您自己的,并且可以更改其格式,那么为什么不这样做:
<Template>
<Name>filename.txt</Name>
<RecordSeparator>\r\n</RecordSeparator>
<FieldCount>16</FieldCount>
</Template>
It's easier to read and to parse, and it's a little bit shorter. 它更易于阅读和解析,并且更短一些。
In the end, I think this is how I would do it: 最后,我认为这是我要做的:
Having this class: 上这堂课:
public class Item
{
public String FileName { get; set; }
public String Separator { get; set; }
public int FieldCount { get; set; }
}
and this private method: 和这个私有方法:
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)
};
}
I could do in code: 我可以用代码来做:
XDocument doc = XDocument.Load("myfile.txt");
List<Item> items = (from template in doc.Elements("Template")
select GetItemFromTemplate(template)).ToList();
This one is a little more efficient: 这一点效率更高:
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
};
If you have always one Template
node: 如果您始终有一个“
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.