Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If I understand your question correct you only want to get the innermost elements that have an attribute <code>ResultCode="ERROR"</code>. For your sample data <code>&lt;PRODUCT&gt;</code> should not be in the result since it has a child element with <code>ResultCode="ERROR"</code>.</p> <p>The <a href="http://msdn.microsoft.com/library/vstudio/bb346432.aspx" rel="nofollow"><code>Descendants</code></a> method returns all descendant elements in the document. Filtering by the attribute solely would therefore include the <code>&lt;PRODUCT&gt;</code>node. So you need to add a check for the children of each element:</p> <pre><code>var doc = XDocument.Load("Test.xml"); var errors = doc.Descendants() .Where(e =&gt; e.Attribute("ResultCode") != null &amp;&amp; e.Attribute("ResultCode").Value == "ERROR" &amp;&amp; !e.Elements().Any(c =&gt; c.Attribute("ResultCode") != null &amp;&amp; c.Attribute("ResultCode").Value == "ERROR")); </code></pre> <p>This will return only those elements that do not have any children with an error.</p> <p>Please note that the check for null can be omitted if each node in your XML has a <code>ResultCode</code> attribute. If not you would otherwise get a <code>NullReferenceException</code>. I would suggest to write a little helper method for that check:</p> <pre><code>public static bool HasError(XElement element) { var resultCode = element.Attribute("ResultCode"); return resultCode != null &amp;&amp; resultCode.Value == "ERROR"; } var errors = doc.Descendants() .Where(e =&gt; HasError(e) &amp;&amp; !e.Elements().Any(c =&gt; HasError(c))); </code></pre> <p>Please also note that this will return elements that have <code>ResultCode="ERROR"</code> even if their parents don't have an error.</p> <p>If your requirements are that an element should only be included in the result if its parent also has an error and if you are not sure that the XML will always be formed like that you will need to write a recursive function:</p> <pre><code>public static IEnumerable&lt;XElement&gt; InnermostErrors(XElement root) { var resultCode = root.Attribute("ResultCode"); if (resultCode == null || resultCode.Value != "ERROR") { yield break; } var childrenWithError = root.Elements().Where(e =&gt; HasError(e)); if (!childrenWithError.Any()) { yield return root; } foreach (var inner in childrenWithError.SelectMany(e =&gt; InnermostErrors(e))) { yield return inner; } } </code></pre>
 

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