It is possible. You must manually connect.
Here is an example of how to do this (msbuild 3.5 or higher is required):
<ItemGroup> <ServerTypeA Include="ServerA;ServerB;"> <MetaDataA>A</MetaDataA> </ServerTypeA> <ServerTypeB Include="ServerB;ServerC;"> <MetaDataB>B</MetaDataB> </ServerTypeB> </ItemGroup> <Target Name="JoinServers" DependsOnTargets="ProcessServerTypeA;ProcessServerTypeB"> <Message Text="%(Joined.Identity) Metadata: %(Joined.MetaDataA)%(Joined.MetaDataB)"/> </Target> <Target Name="ProcessServerTypeA"> <ItemGroup> <Joined Include="%(ServerTypeA.Identity)"> <MetaDataA>%(ServerTypeA.MetaDataA)</MetaDataA> </Joined> </ItemGroup> </Target> <Target Name="ProcessServerTypeB" Inputs="@(ServerTypeB)" Outputs="%(ServerTypeB.Identity)'"> <PropertyGroup> <TempItemName>%(ServerTypeB.Identity)</TempItemName> <TempMetaDataB>%(ServerTypeB.MetaDataB)</TempMetaDataB> <TempIsDuplicate Condition="'%(Joined.Identity)' == '$(TempItemName)'">True</TempIsDuplicate> </PropertyGroup> <ItemGroup> <Joined Condition="'%(Joined.Identity)' == '$(TempItemName)'"> <MetaDataB>$(TempMetaDataB)</MetaDataB> </Joined> <Joined Include="$(TempItemName)" Condition="'$(TempIsDuplicate)' != 'True'"> <MetaDataB>$(TempMetaDataB)</MetaDataB> </Joined> </ItemGroup> </Target>
Running the JoinServers target will result in the following output:
ServerA Metadata: A ServerB Metadata: AB ServerC Metadata: B
Update with best answer.
This question pointed me to a much simpler solution.
Basically you use Transform modifiers with %(Identity) to make the connection.
You can replace all 3 goals from above with the following to get the same result.
<Target Name="JoinServers"> <ItemGroup> <Joined Include="%(Identity)"> <MetaDataA>@(ServerTypeA->'%(MetaDataA)')</MetaDataA> <MetaDataB>@(ServerTypeB->'%(MetaDataB)')</MetaDataB> </Joined> </ItemGroup> <Message Text="%(Joined.Identity) Metadata: %(Joined.MetaDataA)%(Joined.MetaDataB)"/> </Target>
source share