msbuilditemgroup

Cross-Join ItemGroups in MSBuild


Given something like so..

 <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <ConfigFiles Include="*.config" />

            <DatabaseConfig Include="ABC">
                <Database>DB1</Database>
                <CsString>Database</CsString>
            </DatabaseConfig>

            <DatabaseConfig Include="DEF">
                <Database>DB2</Database>
                <CsString>Logging</CsString>
            </DatabaseConfig>
        </ItemGroup>


        <Target Name="test" >
            <!-- Some sort of join here (or somewhere)... -->
         <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
        </Target> 
    </Project>

I'd like the Output to be something like this.. (given two files one.config & two.config)

one.config DB1
two.config DB1
one.config DB2
two.config DB2

(the order is not important, just the full cartesian product of the two ItemGroups)


Solution

  • This seems like a tidy solution:

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <ConfigFiles Include="*.config" />
    
            <DatabaseConfig Include="ABC">
                <Database>DB1</Database>
                <CsString>Database</CsString>
            </DatabaseConfig>
    
            <DatabaseConfig Include="DEF">
                <Database>DB2</Database>
                <CsString>Logging</CsString>
            </DatabaseConfig>
        </ItemGroup>
    
        <Target Name="test" >
            <ItemGroup>
                <Combined Include="@(DatabaseConfig)">
                    <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
                </Combined> 
            </ItemGroup>
        <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
        </Target> 
    </Project>