Копировать метаданные элемента для пакетирования - PullRequest
0 голосов
/ 30 ноября 2011

Это расширение к этому вопросу .
Предположим, я создаю элементы из метаданных другого элемента:

<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.

Есть ли способ скопировать все метаданные А в B без явного указания каждого из них?

Ответы [ 3 ]

2 голосов
/ 01 декабря 2011

Насколько я могу судить, 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>

и вывод цели «Печать»:

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 также копируются.

2 голосов
/ 16 июля 2013

Немного поздно, но мне больше нравится это решение:

<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)', '&#x0D;&#x0A;   ')" />
        <Message Text="B: @(B->'%(Identity) x:%(x) y:%(y) z:%(z) files:%(files)', '&#x0D;&#x0A;   ')" />
    </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
0 голосов
/ 01 декабря 2011

Я не уверен, что получу то, что вам нужно, но вы можете скопировать все A-метеданные в B, как в ответе на связанный вопрос :

<B Include="@(A)">

Следует скопировать все метаданные из А в Б.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...