Отфильтруйте существующую группу элементов, чтобы она включала только файлы, соответствующие определенному условию

Как вы фильтруете существующую ItemGroup на основе определенного условия, такого как расширение файла или метаданные элемента?

В этом примере я буду использовать расширение файла. Я пытаюсь отфильтровать "Нет" ItemGroup, определенную VS, чтобы моя цель могла работать со всеми файлами данного расширения.

Например, может быть определено следующее:

<ItemGroup>
    <None Include="..\file1.ext" />
    <None Include="..\file2.ext" />
    <None Include="..\file.ext2" />
    <None Include="..\file.ext3" />
    <None Include="..\file.ext4" />
</ItemGroup>

Я хочу отфильтровать "Нет" ItemGroup выше, поэтому он включает только расширение ext. Заметьте, что я не хочу указать все расширения для исключения, поскольку они будут меняться в зависимости от проекта, и я пытаюсь сделать свою цель повторно используемой без изменений.

Я попытался добавить Condition в цель:

<Target Name="Test">
    <ItemGroup>
        <Filtered
            Include="@(None)"
            Condition="'%(Extension)' == 'ext'"
            />
    </ItemGroup>
    <Message Text="None: '%(None.Identity)'"/>
    <Message Text="Filtered: '%(Filtered.Identity)'"/>
</Target>

Но, к сожалению, это не сработает. Я получаю следующее для вывода:

Test:
  None: '..\file1.ext'
  None: '..\file2.ext'
  None: '..\file.ext2'
  None: '..\file.ext3'
  None: '..\file.ext4'
  Filtered: ''

Ответы

Ответ 1

<ItemGroup>
  <Filtered Include="@(None)" Condition="'%(Extension)' == '.ext'" />
</ItemGroup>

Ответ 2

Для расширенной фильтрации я предлагаю использовать RegexMatch из Задачи сообщества MSBuild.

В этом примере мы будем фильтровать для Versionnumbers

    <RegexMatch Input="@(Items)" Expression="\d+\.\d+\.\d+.\d+">
        <Output ItemName ="ItemsContainingVersion" TaskParameter="Output" />
    </RegexMatch>

Установить задачи сообщества MSBuild через Nuget: PM > Установить пакет MSBuildTasks или загрузить его здесь

Затем импортируйте его в свой MSBuild Script:

<PropertyGroup>
    <MSBuildCommunityTasksPath>..\.build\</MSBuildCommunityTasksPath>
</PropertyGroup>
<Import Project="$(MSBuildCommunityTasksPath)MsBuild.Community.Tasks.Targets" />