使用项函数

任务和目标中的代码可以调用项函数来获取有关项目中项的信息(在 MSBuild 4.0 及更高版本中)。 这些函数简化了获取不同项的速度,并且比循环访问项更快。

字符串项函数

可以使用 .NET Framework 中的字符串方法和属性对任何项值进行作。 对于 String 方法,请指定方法名称。 对于 String 属性,请在“get_”后面指定属性名称。

对于具有多个字符串的项,字符串方法或属性在每个字符串上运行。

以下示例演示如何使用这些字符串项函数。

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

内部项函数

下表列出了可用于项的内部函数。

功能 Example Description
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')) 返回具有给定元数据名称和值的项。 比较不区分大小写。
WithoutMetadataValue @(MyItems->WithoutMetadataValue('MetadataName', 'MetadataValue')) (MSBuild 17.8 及更高版本)返回没有给定元数据值的项。 比较不区分大小写。

注释

Exists也可以在其他上下文中使用;例如Condition="Exists('path')",在 MSBuild 条件中;或在 Static 属性函数中,例如$([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
  -->

调用 String 方法

如果项函数与方案不匹配,则可以通过使用 new 属性函数从元数据创建字符串对象并调用 String 任何方法来实现类似的效果。 例如,以下代码使用子字符串搜索来筛选目标中的项列表。

<Project>
  <PropertyGroup>
    <SearchString>abc</SearchString>
  </PropertyGroup>

  <ItemGroup>
    <UnfilteredList Include="abcdef;abc;def;xyz"></UnfilteredList>
  </ItemGroup>

  <Target Name="FilterItemList">

    <ItemGroup>
      <FilteredList Include="@(UnfilteredList)" Condition="$([System.String]::new('%(UnfilteredList.Identity)').Contains($(SearchString)))"></FilteredList>
    </ItemGroup>

    <Message Text="Result: @(FilteredList)"/>
  </Target>
</Project>

使用元数据项函数时检测重复项

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 条件

还可以使用属性对项列表执行作,例如筛选项元数据。 有关详细信息,请参阅