Linq to XML selects the basics of a node for an attribute value

I have an xml file that returns a set of elements that are unique in attribute value. This presents a problem since I cannot select 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 the Product class. I can select elements by position, however this becomes a problem if node does not exist. Is there a way to select a node based on the value of its attribute? In the example below, is it possible to get the arr node attribute if the @name = "ATR_FamilyName" attribute? In xpath, it will be:

 doc/arr[@name = 'ATR_FamilyName']/str 

here is my linq request 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.... }; 
+6
source share
3 answers

Like AS-CII's answer, but without using a query expression (other than an external one) and casting to XAttribute and selecting the value of the str element inside an anonymous type:

 select new Product.Product { FamilyName = rt.Descendants("arr") .Where(x => (string) x.Attribute("name") == "ATR_FamilyName") .Select(x => (string) x.Element("str")) .FirstOrDefault(), MorePropertiesToSet.... }; 

Note that using translation for the result of calling Attribute("name") means that if there are any elements that do not have an attribute, the cast results in a null reference (which is not equal to a string literal). If you use the Value property, you will get an exception. Sometimes an exception may be better - if it indicates that the data is fundamentally broken, and you want to know about it, and not just not match the value.

(The same is true for casts from XElement to string .)

+17
source

With LINQ, you can easily select only nodes with the specified attribute, for example:

 var query = from node in results.Descendants("arr") // I believe you could use results.Elements("arr") here where node.Attribute("name").Value == "ATR_FamilyName" select new Product { FamilyName = node.Element("str").Value }; 
+5
source

Use XElement as follows:

 from rt in results.descendants("<node name>") where rt.attribute(attribute name).value == "specified value" select rt 

Sorry for entering from your mobile phone

+2
source

Source: https://habr.com/ru/post/900062/


All Articles