Linq to XML 根据属性值选择节点
我有一个 xml 文件,它返回一组属性值唯一的元素。这提出了一个问题,因为我无法通过名称选择节点:
<doc>
<float name="score">1.2873721</float>
<arr name="2_category">
<long>3021</long>
</arr>
<arr name="ATR_FamilyName">
<str>Some Cookbook </str>
</arr>
<arr name="ATR_IsFamily">
<str>0</str>
</arr>
<arr name="ATR_SellPrice">
<str>49.95</str>
</arr>
<arr name="ATR_VendorId">
<str>ABC</str>
</arr>
<arr name="ATR_VendorName">
<str>WROX</str>
</arr>
</doc>
我正在使用 linq 来填充“Product”类。我可以按位置选择元素,但是如果节点不存在,这就会成为问题。有没有办法根据节点的属性值来选择节点?在下面的示例中,如果@name属性=“ATR_FamilyName”,我可以获得arr节点吗?在 xpath 中它将是:
doc/arr[@name = 'ATR_FamilyName']/str
这是我的 linq to xml 查询:
var query = from rt in results
where (String)rt.Descendants().ElementAt(5).Element("str").Value == "0"
select new Product.Product
{
FamilyName = (String)rt.Descendants().ElementAt(3).Value
// doc/arr[@name = 'ATR_FamilyName']/str - select Family Name is arr/@name 'ATR_FamilyName'
MorePropertiestoset....
};
I have an xml file that returns a set of elements that are unique by a attribute value. This presents a problem, as I can not select a node by its name:
<doc>
<float name="score">1.2873721</float>
<arr name="2_category">
<long>3021</long>
</arr>
<arr name="ATR_FamilyName">
<str>Some Cookbook </str>
</arr>
<arr name="ATR_IsFamily">
<str>0</str>
</arr>
<arr name="ATR_SellPrice">
<str>49.95</str>
</arr>
<arr name="ATR_VendorId">
<str>ABC</str>
</arr>
<arr name="ATR_VendorName">
<str>WROX</str>
</arr>
</doc>
I am using linq to populate a "Product" class. I am able to select the elements by position, however this becomes a problem if the node doesn't exist. Is there a way to select a node based on the value of its attribute? In the below example, can I get the arr node if the @name attribute = "ATR_FamilyName"? In xpath it would be:
doc/arr[@name = 'ATR_FamilyName']/str
here is my linq to xml query:
var query = from rt in results
where (String)rt.Descendants().ElementAt(5).Element("str").Value == "0"
select new Product.Product
{
FamilyName = (String)rt.Descendants().ElementAt(3).Value
// doc/arr[@name = 'ATR_FamilyName']/str - select Family Name is arr/@name 'ATR_FamilyName'
MorePropertiestoset....
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
与 AS-CII 的答案类似,但不使用查询表达式(外部查询表达式除外),并使用
XAttribute
进行强制转换,并选择匿名内的str
元素值类型:请注意,对
Attribute("name")
调用结果使用强制转换意味着如果存在任何不具有该属性的元素,强制转换将导致空引用(不等于字符串文字)。如果您使用Value
属性,您将收到异常。有时,异常可能会更好 - 如果这表明数据从根本上被破坏并且您想要找出它而不是仅仅与值不匹配。(将
XElement
转换为string
也是如此。)Like AS-CII's answer, but without using a query expression (except for the outer one), and with the cast for
XAttribute
, and selecting thestr
element value inside an anonymous type:Note that the use of a cast for the result of the call to
Attribute("name")
means that if there are any elements which don't have the attribute, the cast will result in a null reference (which isn't equal to the string literal). If you use theValue
property, you'll get an exception. Sometimes an exception may be better - if that indicates that the data is fundamentally broken and you want to find out about it rather than just not match the value.(The same is true for the cast of the
XElement
tostring
.)使用 LINQ,您可以轻松地仅选择具有指定属性的节点,如下所示:
With LINQ you can easily select just the nodes that have a specified attribute, like this:
像这样使用
XElement
:抱歉使用手机打字
Use
XElement
like this:Sorry for typing from cell phone
由于
rt
是您各自的 XElement 根,您还可以仅使用扩展方法 XPathSelectElement 像这样:rt.XPathSelectElement("descendant::arr[@name = 'ATR_FamilyName']/str")
With
rt
being your respective XElement root, you could also just use the extension method XPathSelectElement like so:rt.XPathSelectElement("descendant::arr[@name = 'ATR_FamilyName']/str")