Pour autant que je sache, MSBuild ne copie les métadonnées que lorsqu'il existe un mappage un-à-un entre les listes d'éléments d'entrée et de sortie. Dans votre cas, vous commencez avec un élément et vous étendez à de nombreux éléments. Pour contourner ce problème, je suggère d'utiliser batching article:
<?xml version="1.0" encoding="iso-8859-1"?>
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0"
DefaultTargets="Print">
<ItemGroup>
<A Include="A1">
<files>test.htm;test_sol1.htm</files>
<x>a1</x>
<y>b1</y>
<z>c1</z>
</A>
<A Include="A2">
<files>test.proj</files>
<x>a2</x>
<y>b2</y>
<z>c2</z>
</A>
</ItemGroup>
<Target Name="ExpandA">
<ItemGroup>
<ExpandedA Include="%(A.files)">
<Original>%(Identity)</Original>
</ExpandedA>
</ItemGroup>
</Target>
<Target
Name="CopyMetadata"
Outputs="%(ExpandedA.Identity)"
DependsOnTargets="ExpandA">
<PropertyGroup>
<ExpandedAIdentity>%(ExpandedA.Identity)</ExpandedAIdentity>
<ExpandedAOriginal>%(ExpandedA.Original)</ExpandedAOriginal>
</PropertyGroup>
<ItemGroup>
<ExpandedAMetadata Include="@(A)" Condition=" '%(Identity)' == '$(ExpandedAOriginal)' ">
<Expanded>$(ExpandedAIdentity)</Expanded>
</ExpandedAMetadata>
</ItemGroup>
</Target>
<Target Name="Print" DependsOnTargets="CopyMetadata">
<ItemGroup>
<B Include="@(ExpandedAMetadata->'%(Expanded)')" />
</ItemGroup>
<!--Use commas to illustrate that "files" has been expanded-->
<Message Text="A: %(A.files)" />
<Message Text="ExpandedA: @(ExpandedA, ',')" />
<Message Text="ExpandedAMetadata: @(ExpandedAMetadata, ',')" />
<Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z)', ',')" />
</Target>
</Project>
et la sortie de la cible "Imprimer": dans votre question initiale
Print:
A: test.htm;test_sol1.htm
A: test.proj
ExpandedA: test.htm,test_sol1.htm,test.proj
ExpandedAMetadata: A1,A1,A2
B: test.htm x:a1 y:b1 z:c1,test_sol1.htm x:a1 y:b1 z:c1,test.proj x:a2 y:b2 z:c2
ExpandedA
est similaire à B
; c'est la version étendue de A
mais sans aucune métadonnée. Ensuite, je lance la cible CopyMetadata
une fois pour chaque article en ExpandedA
(grâce à la mise en lots des articles). À chaque exécution, l'élément original A
est copié dans le groupe d'articles ExpandedAMetadata
avec toutes ses métadonnées. Les métadonnées Original
sont utilisées pour garantir que l'élément A
correct est associé à chaque fichier. Enfin, dans la cible Print
, B
est construit en utilisant une transformation d'élément, de sorte que toutes les métadonnées de ExpandedAMetadata
sont également copiées.
Belle solution, j'aime la façon dont vous avez utilisé le dosage pour le faire. Mais chaque fois que j'ai besoin de copier des métadonnées, j'ai besoin d'écrire une cible "CopyMetadata" supplémentaire pour faire le batching. Je me retrouve à copier des métadonnées trop souvent, j'espérais qu'il y aurait une tâche "CopyMetadata" ou quelque chose de similaire qui me permettrait de le faire sans avoir à écrire une autre cible pour chaque opération de copie. (peut-être une tâche en ligne "CopyMetadata" ...) –