jamietre / CsQuery

CsQuery is a complete CSS selector engine, HTML parser, and jQuery port for C# and .NET 4.
Other
1.15k stars 249 forks source link

Select element by attribute value #163

Open marcselman opened 10 years ago

marcselman commented 10 years ago

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.

jamietre commented 10 years ago

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?