项定义Item definitions

MSBuild 2.0 版本可让你使用 ItemGroup 元素在项目文件中实现项目的静态声明。MSBuild 2.0 enables the static declaration of items in project files by using the ItemGroup element. 但是,只能在项级别添加元数据,即使所有项的元数据均相同,也是如此。However, metadata may be added only at the item level, even if the metadata is identical for all items. 从 MSBuild 3.5 开始引入了一个名为 ItemDefinitionGroup 的项目元素,从而克服了这一限制。Starting in MSBuild 3.5, a project element named ItemDefinitionGroup overcomes this limitation. 使用 ItemDefinitionGroup 可以定义一组项定义,这些项定义将默认元数据值添加到命名项类型中的所有项中。ItemDefinitionGroup lets you define a set of item definitions, which add default metadata values to all items in the named item type.

ItemDefinitionGroup 元素紧跟在项目文件的 Project 元素之后。The ItemDefinitionGroup element appears immediately after the Project element of the project file. 项定义提供以下功能:Item definitions provide the following functionality:

  • 可为目标外部的项定义全局默认元数据。You can define global default metadata for items outside a target. 也就是说,相同的元数据适用于指定类型的所有项。That is, the same metadata applies to all items of the specified type.

  • 项目类型可以有多个定义。Item types can have multiple definitions. 当其他元数据规范添加到该类型中时,最新的规范优先。When additional metadata specifications are added to the type, the last specification takes precedence. (元数据遵循与属性相同的导入顺序。)(The metadata follows the same import order as properties follow.)

  • 元数据可具有累加性。Metadata can be additive. 例如,根据要设置的属性,CDefines 值可以有条件地累积。For example, CDefines values are accumulated conditionally, depending on the properties that are being set. 例如 MT;STD_CALL;DEBUG;UNICODEFor example, MT;STD_CALL;DEBUG;UNICODE.

  • 可删除元数据。Metadata can be removed.

  • 可使用条件来控制元数据的包含。Conditions can be used to control the inclusion of metadata.

项元数据默认值Item metadata default values

在 ItemDefinitionGroup 中定义的项元数据仅是默认元数据的声明。Item metadata that is defined in an ItemDefinitionGroup is just a declaration of default metadata. 除非定义一个使用 ItemGroup 包含元数据值的项,否则元数据不适用。The metadata does not apply unless you define an Item that uses an ItemGroup to contain the metadata values.

备注

在本主题的诸多示例中,尽管显示了 ItemDefinitionGroup 元素,但为清楚起见,省略了相应的 ItemGroup 定义。In many of the examples in this topic, an ItemDefinitionGroup element is shown but its corresponding ItemGroup definition is omitted for clarity.

ItemGroup 中显式定义的元数据优先于 ItemDefinitionGroup 中的元数据。Metadata explicitly defined in an ItemGroup takes precedence over metadata in ItemDefinitionGroup. ItemDefinitionGroup 中的元数据仅应用于 ItemGroup 中未定义的元数据。Metadata in ItemDefinitionGroup is applied only for undefined metadata in an ItemGroup. 例如:For example:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <n>n1</n>
    </i>
</ItemDefinitionGroup>
<ItemGroup>
    <i Include="a">
        <o>o1</o>
        <n>n2</n>
    </i>
</ItemGroup>

在本例中,默认元数据“m”应用于项“i”,这是由于项“i”没有显式定义元数据“m”。In this example, the default metadata "m" is applied to Item "i" because metadata "m" is not explicitly defined by Item "i". 但是,默认元数据“n”无法应用于项“i”,这是由于元数据“n”已经由项“i”定义。However, default metadata "n" is not applied to Item "i" because metadata "n" is already defined by Item "i".

备注

XML 元素和参数名均区分大小写。XML Element and Parameter names are case-sensitive. 项元数据和项/属性名均不区分大小写。Item metadata and Item/Property names are not case-sensitive. 因此,应将名称中仅大小写不同的 ItemDefinitionGroup 项视作同一个 ItemGroup。Therefore, ItemDefinitionGroup items that have names that differ only by case should be treated as the same ItemGroup.

值源Value sources

ItemDefinitionGroup 中定义的元数据的值可能来自许多不同的源,如下所示:The values for metadata that is defined in an ItemDefinitionGroup can come from many different sources, as follows:

  • PropertyGroup 属性PropertyGroup Property

  • ItemDefinitionGroup 中的项Item from an ItemDefinitionGroup

  • ItemDefinitionGroup 项上的项转换Item transform on an ItemDefinitionGroup Item

  • 环境变量Environment variable

  • 全局属性(来自 MSBuild.exe 命令行) Global property (from the MSBuild.exe command line)

  • 保留属性Reserved property

  • ItemDefinitionGroup 中项上的常见元数据Well-known metadata on an Item from an ItemDefinitionGroup

  • CDATA 节 <![CDATA[anything here is not parsed]]>CDATA section <![CDATA[anything here is not parsed]]>

备注

ItemGroup 中的项元数据在 ItemDefinitionGroup 元数据声明中无用,这是因为已在 ItemGroup 元素之前处理 ItemDefinitionGroup 元素。Item metadata from an ItemGroup is not useful in an ItemDefinitionGroup metadata declaration because ItemDefinitionGroup elements are processed before ItemGroup elements.

累加性和多个定义Additive and multiple definitions

当添加定义或使用多个 ItemDefinitionGroup 时,请记住以下几点:When you add definitions or use multiple ItemDefinitionGroups, remember the following:

  • 将其他元数据规范添加到此类型中。Additional metadata specification is added to the type.

  • 最新规范优先。The last specification takes precedence.

当拥有多个 ItemDefinitionGroup 时,每个后续规范将其元数据添加至先前的定义。When you have multiple ItemDefinitionGroups, each subsequent specification adds its metadata to the previous definition. 例如:For example:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <n>n1</n>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <o>o1</o>
    </i>
</ItemDefinitionGroup>

在本例中,向“m”和“n”添加元数据“o”。In this example, the metadata "o" is added to "m" and "n".

此外,还可以添加先前定义的元数据值。In addition, previously defined metadata values can also be added. 例如:For example:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <m>%(m);m2</m>
    </i>
</ItemDefinitionGroup>

在本例中,元数据“m”先前定义的值 (m1) 被添加至新值 (m2),因此最终值为“m1;m2”。In this example, the previously defined value for metadata "m" (m1) is added to the new value (m2), so that the final value is "m1;m2".

备注

在相同的 ItemDefinitionGroup 中也可能出现这种情况。This can also occur in the same ItemDefinitionGroup.

当替代先前定义的元数据时,最新规范优先。When you override the previously defined metadata, the last specification takes precedence. 在下列示例中,元数据“m”的最终值从“m1”变为“m1a”。In the following example, the final value of metadata "m" goes from "m1" to "m1a".

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <m>m1a</m>
    </i>
</ItemDefinitionGroup>

在 ItemDefinitionGroup 中使用条件Use conditions in an ItemDefinitionGroup

可使用 ItemDefinitionGroup 中的条件来控制元数据的包含。You can use conditions in an ItemDefinitionGroup to control the inclusion of metadata. 例如:For example:

<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>

在这种情况下,仅当“Configuration”属性的值为“Debug”时,才包括项“i”上的默认元数据“m1”。In this case, the default metadata "m1" on item "i" is included only if the value of the "Configuration" property is "Debug".

备注

在条件中仅支持本地元数据引用。Only local metadata references are supported in conditions.

对项(而非定义组)而言,在先前的 ItemDefinitionGroup 中定义的元数据的引用是本地的。References to metadata defined in an earlier ItemDefinitionGroup are local to the item, not the definition group. 也就是说,引用的范围特定于项。That is, the scope of the references are item-specific. 例如:For example:

<ItemDefinitionGroup>
    <test>
        <yes>1</yes>
    </test>
    <i>
        <m>m0</m>
        <m Condition="'%(test.yes)'=='1'">m1</m>
    </i>
</ItemDefinitionGroup>

在上述示例中,项“i”在其条件中引用项“test”。In the above example, item "i" references item "test" in its Condition. 此种情况永远不会为 true,因为 MSBuild 将 ItemDefinitionGroup 中对另一个项的元数据的引用解释为空字符串。This Condition will never be true because MSBuild interprets a reference to another item's metadata in an ItemDefinitionGroup as the empty string. 因此,“m”将设置为“m0”。Therefore, "m" would be set to "m0."

  <ItemDefinitionGroup>
    <i>
      <m>m0</m>
      <yes>1</yes>
      <m Condition="'%(i.yes)'=='1'">m1</m>
    </i>
  </ItemDefinitionGroup>

在上述示例中,“m”将设置为值“m1”,作为项“yes”的条件引用项“i”的元数据值。In the above example, "m" would be set to the value "m1" as the Condition references item "i"'s metadata value for item "yes."

替代和删除元数据Override and delete metadata

通过将元数据值设置为其他值,在 ItemDefinitionGroup 元素中定义的元数据可以在之后的 ItemDefinitionGroup 元素中被替代。Metadata defined in an ItemDefinitionGroup element can be overridden in a later ItemDefinitionGroup element by setting the metadata value to another value. 还可通过将元数据项设置为空值,高效删除元数据项。You can also effectively delete a metadata item by setting it to an empty value. 例如:For example:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
    </i>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
    <i>
        <m></m>
    </i>
</ItemDefinitionGroup>

项“i”仍包含元数据“m”,但此时它的值为空。The item "i" still contains metadata "m", but its value is now empty.

元数据范围Scope of metadata

ItemDefinitionGroups 在定义的位置具有全局范围和全局属性。ItemDefinitionGroups have global scope on defined and global properties wherever they are defined. ItemDefinitionGroup 中的默认元数据定义可自引用。Default metadata definitions in an ItemDefinitionGroup can be self-referential. 例如,以下示例使用了一个简单的元数据引用:For example, the following uses a simple metadata reference:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <m>%(m);m2</m>
    </i>
</ItemDefinitionGroup>

还可使用限定的元数据引用:A qualified metadata reference can also be used:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <m>%(i.m);m2</m>
    </i>
</ItemDefinitionGroup>

但是,以下项无效:However, the following is not valid:

<ItemDefinitionGroup>
    <i>
        <m>m1</m>
        <m>@(x)</m>
    </i>
</ItemDefinitionGroup>

从 MSBuild 3.5 开始,ItemGroups 可以自引用。Beginning in MSBuild 3.5, ItemGroups can also be self-referential. 例如:For example:

<ItemGroup>
    <item Include="a">
        <m>m1</m>
        <m>%(m);m2</m>
    </item>
</ItemGroup>

请参阅See also