Основное правило - атрибуты вообще не имеют идентичности - они доступны только как боковые биты, прикрепленные к узлу . Хорошо думать о них как о несуществующих, пока у вас не появится первый узел. Вы также можете думать о них как о совершенно второсортных гражданах в мире XPath и XSLT. Каждый раз, когда вы используете их в условиях выбора, это похоже на переход от соединения к курсору в SQL, и каждый раз, когда вы используете «для» вместо «применять», происходит то же самое.
Другой способ выразить это - единственный реальный, эффективный «индекс», который у вас есть, это тот, который содержит все XPath-ы в документе (.Net фактически создает Hashtable из XPaths => совпадение с постоянным временем). Причиной того, что «apply» является привилегированным, является то, что он гарантирует чисто функциональную обработку - вы можете запускать все совпадающие, применяя apply в отдельных потоках без синхронизации и разделения памяти - вы просто объединяете их результаты.
Третий способ взглянуть на это, который натянут, представьте, что ваши теги являются таблицами SQL и что у вас есть только суррогатные PK-ы и FK-ы - ничего другого, что вы действительно можете выбрать, кроме «все из T1 и все связанные с ним» им от Т2 ". Для любого приличного движка SQL это похоже на усилия с 0 затратами - он просто читает один хороший индексный элемент за элементом, так как сама структура составляет 1-1 в вашем запросе. Все остальное стоит намного дороже.
После того, как вы выбрали теги, и шаблоны соответствовали и запустились, тогда дешево просто получить значения атрибутов - до тех пор, пока вы просто преобразуете / визуализируете их. Тесты Attrib в конце XPath также достаточно дешевы - опять же, поскольку выбран последний тег / узел, а теперь это всего лишь небольшой фильтр поверх него.
Итак, механизм XSLT и выбор XPath в целом имеют очень веские основания для полного игнорирования атрибутов - perf.