CsQuery icon indicating copy to clipboard operation
CsQuery copied to clipboard

Select element by attribute value

Open marcselman opened this issue 11 years ago • 1 comments

Hi,

First of all great library!

I'm trying to retrieve all elements which have an attribute with a value that starts with "resource://" so I can replace the contents of the attribute with a string resource from an external file.

This is what I have right now. It works, but I was wondering if there is a better way of doing it.

var resourceAttributes = dom["*"].Where(n => n.Attributes != null && n.Attributes.Any(a => a.Value.StartsWith("resource://"))).Dump();
foreach (var resourceAttribute in resourceAttributes)
{
    foreach (var attribute in resourceAttribute.Attributes.Where(a => a.Value.StartsWith("resource://")).ToList())
    {
        resourceAttribute[attribute.Key] = "the external resource value";
    }
}

A nested foreach loop seems a little heavy. Could it be optimized in any way?

Thank you.

marcselman avatar Sep 19 '14 09:09 marcselman

So you're trying to match any attribute, e.g. not just certain named attributes like img? I can't think of an easy way to optimize targeting the elements - the index is actually capable of doing this (since it creates an index key for anything with an attribute) but there's no hook to use it. It's only designed to match specific attribute names, so to get that performance benefit it would require a change.

That said I am not sure I understand why you need a nested loop. The inner loop in your example seems to be doing the exact same filter as the original code that creates resourceAttributes -- why can't you just iterate over the contents of resourceAttributes directly?

jamietre avatar Sep 19 '14 12:09 jamietre