这是this question的扩展 假设我正在从其他项目的元数据中创建项目:
<ItemGroup>
<A>
<files>f1;f2;f3;...</files>
<x>...</x>
<y>...</y>
<z>...</z>
...
</A>
<B Include="%(A.files)">
<x>%(A.x)</x>
<y>%(A.y)</y>
<z>%(A.z)</z>
...
</B>
</ItemGroup>
%(A.files)
是由;
分隔的文件列表,因此对于每个A项,我创建了许多B项(每个文件一个)。
但是,当我处理B
项时,我经常需要原始的A
项元数据。在此示例中,我将每个元数据从A
手动复制到B
。
有没有办法将所有A的元数据复制到B而不明确指定它们中的每一个?
答案 0 :(得分:2)
据我所知,MSBuild只在输入和输出项列表之间存在一对一映射时才复制元数据。在您的情况下,您从一个项目开始并扩展到许多项目。为了解决这个问题,我建议使用项目批处理:
<?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>
和&#34;打印&#34;的输出目标:
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
与原始问题中的B
类似;它是A
的扩展版本,但没有任何元数据。然后我为CopyMetadata
中的每个项目运行一次ExpandedA
目标(由于项目批处理)。每次运行时,原始A
项目及其所有元数据都将复制到ExpandedAMetadata
项目组。 Original
元数据用于确保正确的A
项与每个文件相关联。最后,在Print
目标中,使用项目转换构建B
,以便同时复制ExpandedAMetadata
中的所有元数据。
答案 1 :(得分:2)
不太晚,但我更喜欢这个解决方案:
<B Include="@(A->Metadata('files'))" />
完整示例:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<A Include="A1">
<files>a1_file1.htm;a1_file2.htm</files>
<x>a1</x>
<y>b1</y>
<z>c1</z>
</A>
<A Include="A2">
<files>a2_file.proj</files>
<x>a2</x>
<y>b2</y>
<z>c2</z>
</A>
<B Include="@(A->Metadata('files'))" />
</ItemGroup>
<Target Name="Build">
<Message Text="A: @(A->'%(Identity) x:%(x) y:%(y) z:%(z) files:%(files)', '
 ')" />
<Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z) files:%(files)', '
 ')" />
</Target>
</Project>
输出:
Build:
A: A1 x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
A2 x:a2 y:b2 z:c2 files:a2_file.proj
B: a1_file1.htm x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
a1_file2.htm x:a1 y:b1 z:c1 files:a1_file1.htm;a1_file2.htm
a2_file.proj x:a2 y:b2 z:c2 files:a2_file.proj
答案 2 :(得分:0)
我不确定我是否得到了你需要的东西,但你可以像answer for related question一样将所有A metedata复制到B:
<B Include="@(A)">
它应该将所有metedata从A复制到B.