Note that there are some explanatory texts on larger screens.

plurals
  1. POLINQ to XML: filter a query using XElement.Attributes() collection with both XName and Value
    primarykey
    data
    text
    <p>Using LINQ to XML, XElements and XAttributes I'd like to filter a query using an exact match on an XElement's Attributes() IEnumerable collection of XName/Value pairs, against a provided IEnumerable Attributes collection of XName/Value pairs. </p> <pre><code>&lt;container&gt; &lt;!-- logical group of settings --&gt; &lt;group name="group-one"&gt; &lt;!-- setting with multiple key-value key options to return value --&gt; &lt;setting&gt; &lt;key app="a" command="go" /&gt; &lt;key app="a" type="z" command="go" /&gt; &lt;key app="a" type="z" flag="1" command="go" /&gt; &lt;key app="a" type="z" target="OU812"/&gt; &lt;value&gt;group-one item value A&lt;/value&gt; &lt;/setting&gt; &lt;setting&gt; &lt;key app="a" /&gt; &lt;key app="a" type="z" /&gt; &lt;key app="a" type="z" flag="1" /&gt; &lt;key app="c" type="z" command="go" /&gt; &lt;value&gt;group-one item value B&lt;/value&gt; &lt;/setting&gt; ... ... &lt;/group&gt; &lt;group name="group-two"&gt; ... ... &lt;/group&gt; &lt;/container&gt; </code></pre> <p>I suspect using Attributes().SequenceEqual() with a custom IEqualityComparer to compare both XAttribute.XName and XAttribute.Value is the way to go, but the sequence never matches because XElement("key").Attributes() returns a collection of all attributes for all elements in a given element. I have tried any number linq queries similar to following code snippet, including nested queries and using the "let" statement, but I can't seem to get it right. </p> <pre><code>var myAttributes = new List&lt;XAttribute&gt; { new XAttribute("app", "a"), new XAttribute("type", "z") }; var xGroup = doc.Elements("group").First(g=&gt;g.Attribute("name").Value==groupName); var xSetting = (from s in xGroup.Elements("setting") // AttributesComparer() compares both the XAttribute.XName and XAttribute.Value properties to determine equality where s.Elements("key").Attributes().SequenceEqual(myAttributes, new AttributesComparer()) select s).FirstOrDefault(); var xValue = xSetting.Element("value"); </code></pre> <p>It should return an XElement representing <code>&lt;value&gt;group-one item value B&lt;/value&gt;</code></p> <p>For now, I have settled on using XPathSelectElement() -- passing an XPath string built from the name/values in the provided XAttributes() collection. In this case, the generated string would be:</p> <pre><code>group[@name='group-one']/setting[key[@app='n' and @type='z' and count(@*)=2]]/value </code></pre> <p>But, I'm generally resistant to looping through collections to build strings in an application. I have been hammering away at this for a while now, and unfortunately, I am stumped as to how to impliment a more "elegant" solution using a compact linq query (or series of queries) with existing methods.</p> <p>Any feedback and/or suggestions would be greatly appreciated!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload