我正在使用现有的XML文档,其结构(部分)如此:
<Group>
<Entry>
<Name> Bob </Name>
<ID> 1 </ID>
</Entry>
<Entry>
<Name> Larry </Name>
</Entry>
</Group>
我正在使用LINQ to XML查询XDocument以检索所有这些条目,如下所示:
var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
select new
{
name = (string)g.element("Name").Value,
id = g.Elements("ID").Count() > 0 ? (string)g.Element("ID").Value : "none"
};
“ID”元素并不总是存在,因此我对此的解决方案是上面的Count()爵士乐。但我想知道是否有人有更好的方法来做到这一点。我仍然对这些新东西感到满意,我怀疑可能有一种更好的方法来做到这一点,而不是我现在正在做的事情。
有没有更好/更优选的方式来做我想要的事情?
答案 0 :(得分:23)
XElement实际上interesting explicit conversion operators在这种情况下做了正确的事情。
因此,您实际上很少需要访问.Value
属性。
这就是投影所需的全部内容:
var items =
from g in xDocument.Root.Descendants("Group").Elements("Entry")
select new
{
name = (string) g.Element("Name"),
id = (string) g.Element("ID") ?? "none",
};
如果您希望在匿名类型中使用ID
的值作为整数:
var items =
from g in xDocument.Root.Descendants("Group").Elements("Entry")
select new
{
name = (string) g.Element("Name"),
id = (int?) g.Element("ID"),
};
答案 1 :(得分:3)
在类似的情况下,我使用了扩展方法:
public static string OptionalElement(this XElement actionElement, string elementName)
{
var element = actionElement.Element(elementName);
return (element != null) ? element.Value : null;
}
用法:
id = g.OptionalElement("ID") ?? "none"
答案 2 :(得分:1)
怎么样:
var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
let idEl = g.Element("ID")
select new
{
name = (string)g.element("Name").Value,
id = idEl == null ? "none" : idEl.Value;
};
如果这个barfs,那么FirstOrDefault()
等可能有用,否则只需使用扩展方法(如已建议的那样)。