Filter an existing itemgroup so it only includes files that match some condition
Solution 1
<ItemGroup>
<Filtered Include="@(None)" Condition="'%(Extension)' == '.ext'" />
</ItemGroup>
Solution 2
For advanced filtering I suggest using the RegexMatch
from MSBuild Community Tasks.
In this Example we will Filter for Versionnumbers
<RegexMatch Input="@(Items)" Expression="\d+\.\d+\.\d+.\d+">
<Output ItemName ="ItemsContainingVersion" TaskParameter="Output" />
</RegexMatch>
Install MSBuild Community Tasks via Nuget: PM> Install-Package MSBuildTasks or download it here
Then Import it in your MSBuild Script:
<PropertyGroup>
<MSBuildCommunityTasksPath>..\.build\</MSBuildCommunityTasksPath>
</PropertyGroup>
<Import Project="$(MSBuildCommunityTasksPath)MsBuild.Community.Tasks.Targets" />
Related videos on Youtube
Comments
-
Kaleb Pederson over 1 year
How do you filter an existing ItemGroup based on a specific condition, such as file extension or the item's metadata?
For this example, I'll use the file extension. I'm trying to filter the 'None' ItemGroup defined by VS so that my target can operate on all files of a given extension.
For example, the following may be defined:
<ItemGroup> <None Include="..\file1.ext" /> <None Include="..\file2.ext" /> <None Include="..\file.ext2" /> <None Include="..\file.ext3" /> <None Include="..\file.ext4" /> </ItemGroup>
I want to filter the 'None' ItemGroup above so it only includes the
ext
extension. Note that I do not want to specify all the extensions to exclude, as they'll vary per project and I'm trying to make my target reusable without modification.I've tried adding a
Condition
within a target:<Target Name="Test"> <ItemGroup> <Filtered Include="@(None)" Condition="'%(Extension)' == 'ext'" /> </ItemGroup> <Message Text="None: '%(None.Identity)'"/> <Message Text="Filtered: '%(Filtered.Identity)'"/> </Target>
But sadly, it doesn't work. I get the following for output:
Test: None: '..\file1.ext' None: '..\file2.ext' None: '..\file.ext2' None: '..\file.ext3' None: '..\file.ext4' Filtered: ''
-
Ilya Kozhevnikov over 11 yearsI believe %(Extension) needs to be '.ext'
-
Ilya KozhevnikovI mean it literally needs to be '.ext', as in with a dot as first char, works just fine then.
-
-
Marcin Wisnicki over 8 yearsThis doesn't work for me.
error MSB4190: The reference to the built-in metadata "Extension" at posi tion 1 is not allowed in this condition "'%(Extension)' == '.ext'".
-
VeeTheSecond almost 6 yearsI second the
<Target>
comment, with one addition: In a normal programming language, you would expect the<Filtered>
ItemGroup to be scoped to the<Target>
it is contained in. Not so in MSBuild: If you define your<Filtered>
inside a target, it will be available to other targets, so if you need the ItemGroup in another target, just set yourBeforeTargets
attribute for the new<Target>
to be the target where you need the ItemGroup. -
Mostafa Armandi almost 4 years@MarcinWisnicki make sure you put the ItemGroup into a target when you want to access well-known item metadata. Otherwise you get that error.