I actually have 2 questions:
How can I filter a list of files (in an ItemGroup) by extension?
I have two lists of files read out of XML files via XMLPeek that I would like to merge together based on a conditional. Can this be done in MSBuild?
Currently, I have something like this:
<Target Name="GetExportFileList">
<!-- Can't use XPath to filter the value by extension because MSBuild doesn't support XPath 2.0's ends-with() function -->
<XmlPeek XmlInputPath="$(XmlFile)"
Query = "//File[not(./@value = '') and not(./@value = preceding::File/@value)]/@value">
<!-- this file list will have files with two different extensions, we'll call them .ext1 and ext2 files - need a way to split this into two ItemGroups each containing only one of the file types -->
<Output TaskParameter="Result"
ItemName="ReferencedFiles" />
</XmlPeek>
<!-- .ext2 files are XML and contain references to other .ext1 files -->
<XmlPeek XmlInputPath="$(DirectlyReferencedExt2Files)"
Query="//Ext1[not(./@FilePath = '')]/@FilePath">
<Output TaskParameter="Result"
ItemName="IndirectlyReferencedExt1Files" />
</XmlPeek>
<!-- combine the two lists -->
<ItemGroup>
<AllExt1Files Include="@IndirectlyReferencedExt1Files" />
<AllExt1Files Include="@DirectlyReferencedExt1Files" Exclude="@AllExt1Files" />
</ItemGroup>
</Target>
So to recap:
There's probably some really simple way to do this, but I'm having trouble groking how MSBuild works and where to find the reference for what I'm trying to do (MSDN was more confusing than helpful :))
Thanks!
This is all standard msbuild functionality:
<ItemGroup>
<ReferencedFiles Include="a.ext1;b.ext1;c.ext2;d.ext2"/>
</ItemGroup>
<Target Name="FilterIt">
<ItemGroup>
<DirectlyReferencedExt1Files Include="%(ReferencedFiles.Identity)" Condition="'%(Extension)'=='.ext1'" />
<DirectlyReferencedExt2Files Include="%(ReferencedFiles.Identity)" Condition="'%(Extension)'=='.ext2'" />
<AllOfThem Include="@(DirectlyReferencedExt1Files);@(DirectlyReferencedExt2Files)" />
</ItemGroup>
<Message Text="@(DirectlyReferencedExt1Files)" />
<Message Text="@(DirectlyReferencedExt2Files)" />
<Message Text="@(AllOfThem)" />
</Target>
Note: your questions are duplicates but because you ask two of them it's hard to find exact duplicates as SO requires.. See How do you filter an ItemGroup? for instance, and MSBuild ItemGroup with condition, and How can I merge two ItemGroups in MSBuild