項目関数を操作する

タスクとターゲット内のコードでは、項目用の関数を呼び出し、プロジェクトのその項目に関する情報を取得できます (MSBuild 4.0 以降)。 これらの関数により、個別の項目の取得が簡素化され、項目間をループ処理するよりも高速になります。

文字列項目関数

.NET Framework の String メソッドと String プロパティを利用し、あらゆる項目値を操作できます。 String メソッドの場合、メソッド名を指定します。 String プロパティの場合、"get_" の後にプロパティ名を指定します。

項目に複数の文字列が含まれる場合、String メソッドまたはプロパティは各文字列で実行されます。

次は、これらの文字列項目関数の使用方法を示す例です。

<ItemGroup>
    <theItem Include="andromeda;tadpole;cartwheel" />
</ItemGroup>

<Target Name = "go">
    <Message Text="IndexOf  @(theItem->IndexOf('r'))" />
    <Message Text="Replace  @(theItem->Replace('tadpole', 'pinwheel'))" />
    <Message Text="Length   @(theItem->get_Length())" />
    <Message Text="Chars    @(theItem->get_Chars(2))" />
</Target>

  <!--
  Output:
    IndexOf  3;-1;2
    Replace  andromeda;pinwheel;cartwheel
    Length   9;7;9
    Chars    d;d;r
  -->

組み込み項目関数

下の表は、項目に利用できる組み込み関数をまとめたものです。

関数 説明
Combine @(MyItems->Combine('path')) 指定した相対パスがすべての入力項目に追加された、一連の新しい項目を返します。
Count @(MyItems->Count()) 項目の数を返します。
DirectoryName @(MyItems->DirectoryName()) 項目ごとに Path.DirectoryName の等価を返します。
Distinct @(MyItems->Distinct()) 別個の Include 値を含む項目を返します。 メタデータは無視されます。 比較では、大文字と小文字が区別されません。
DistinctWithCase @(MyItems->DistinctWithCase()) 別個の itemspec 値を含む項目を返します。 メタデータは無視されます。 比較では、大文字と小文字を区別します。
Exists @(MyItems->Exists()) 一連の項目を、ディスク上に実際に存在する項目にフィルター処理します。
GetPathsOfAllDirectoriesAbove @(MyItems->GetPathsOfAllFilesAbove()) 一連の項目を指定すると、すべての上位ディレクトリを示す項目が返されます。 順序は保証されません。
Reverse @(MyItems->Reverse()) 項目を逆の順序で返します。
AnyHaveMetadataValue @(MyItems->AnyHaveMetadataValue("MetadataName", "MetadataValue")) 特定のメタデータの名前と値が項目に含まれているかどうかを示す boolean を返します。 比較では、大文字と小文字が区別されません。
ClearMetadata @(MyItems->ClearMetadata()) メタデータを消して項目を返します。 itemspec のみが保持されます。
HasMetadata @(MyItems->HasMetadata("MetadataName")) 特定のメタデータ名を含む項目を返します。 比較では、大文字と小文字が区別されません。
Metadata @(MyItems->Metadata("MetadataName")) メタデータ名が含まれるメタデータの値を返します。 返される項目は、ソースの値と同じメタデータを持ちます。
WithMetadataValue @(MyItems->WithMetadataValue("MetadataName", "MetadataValue")) 特定のメタデータの名前と値を含む項目を返します。 比較では、大文字と小文字が区別されません。

Note

Exists は他のコンテキストでも使用できます。たとえば、MSBuild の条件では Condition="Exists('path')"静的プロパティ関数では $([System.IO.File]::Exists("path")) のようになります。

次は、組み込み項目関数の使用方法を示す例です。

<ItemGroup>
    <TheItem Include="first">
        <Plant>geranium</Plant>
    </TheItem>
    <TheItem Include="second">
        <Plant>algae</Plant>
    </TheItem>
    <TheItem Include="third">
        <Plant>geranium</Plant>
    </TheItem>
</ItemGroup>

<Target Name="go">
    <Message Text="MetaData:    @(TheItem->Metadata('Plant'))" />
    <Message Text="HasMetadata: @(theItem->HasMetadata('Plant'))" />
    <Message Text="WithMetadataValue: @(TheItem->WithMetadataValue('Plant', 'geranium'))" />
    <Message Text=" " />
    <Message Text="Count:   @(theItem->Count())" />
    <Message Text="Reverse: @(theItem->Reverse())" />
</Target>

  <!--
  Output:
    MetaData:    geranium;algae;geranium
    HasMetadata: first;second;third
    WithMetadataValue: first;third

    Count:   3
    Reverse: third;second;first
  -->

Metadata 項目関数を使用する場合の重複の検出

Metadata 項目関数は、ソース項目の元のメタデータを保持します。 これは、返される項目が重複しているかどうかを検討する際に、いくつかの影響を及ぼします。 重複する項目の処理方法を制御するには、KeepDuplicates 属性を使用できます。 また、必要のないメタデータは、RemoveMetadata を追加することで削除することもできます。この場合、重複を検出するときは値自体のみが考慮されます。

  <Target Name="MetadataToItem">
    <ItemGroup>
      <Sample Include="AAA" SomeItems="1;2;3" />
      <Sample Include="BBB" SomeItems="3;4;5" />
    </ItemGroup>

    <ItemGroup>
      <AllSomeItems Include="@(Sample->Metadata('SomeItems'))" KeepDuplicates="false" />
    </ItemGroup>
    <Message Text="AllSomeItems is @(AllSomeItems)" />
  </Target>

出力は次のようになります。

MetadataToItem:
  AllSomeItems is 1;2;3;3;4;5

コードを次のように変更すると、重複する項目値が正常に検出されて削除されます。

    <ItemGroup>
      <AllSomeItems Include="@(Sample->Metadata('SomeItems'))" KeepDuplicates="false" RemoveMetadata="SomeItems" />
    </ItemGroup>

MSBuild 条件関数

関数 HasTrailingSlash は項目関数ではありません。 これは、Condition 属性と一緒に使用することができます。 「MSBuild の条件」を参照してください。

属性を使用して、項目メタデータのフィルター処理など、項目リストに対して操作を実行することもできます。 詳細については、「MSBuild 項目」をご覧ください。