【问题标题】:Cross-Join ItemGroups in MSBuildMSBuild 中的交叉连接项组
【发布时间】:2013-04-09 23:08:37
【问题描述】:

鉴于这样的事情..

 <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <ConfigFiles Include="*.config" />

            <DatabaseConfig Include="ABC">
                <Database>DB1</Database>
                <CsString>Database</CsString>
            </DatabaseConfig>

            <DatabaseConfig Include="DEF">
                <Database>DB2</Database>
                <CsString>Logging</CsString>
            </DatabaseConfig>
        </ItemGroup>


        <Target Name="test" >
            <!-- Some sort of join here (or somewhere)... -->
         <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
        </Target> 
    </Project>

我希望输出是这样的......(给定两个文件 one.config 和 two.config)

one.config DB1
two.config DB1
one.config DB2
two.config DB2

(顺序不重要,只是两个 ItemGroup 的全笛卡尔积)

【问题讨论】:

    标签: msbuild itemgroup


    【解决方案1】:

    这似乎是一个整洁的解决方案:

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <ConfigFiles Include="*.config" />
    
            <DatabaseConfig Include="ABC">
                <Database>DB1</Database>
                <CsString>Database</CsString>
            </DatabaseConfig>
    
            <DatabaseConfig Include="DEF">
                <Database>DB2</Database>
                <CsString>Logging</CsString>
            </DatabaseConfig>
        </ItemGroup>
    
        <Target Name="test" >
            <ItemGroup>
                <Combined Include="@(DatabaseConfig)">
                    <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
                </Combined> 
            </ItemGroup>
        <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
        </Target> 
    </Project>
    

    【讨论】:

    • 这不会以您想要的方式组合项目元数据或产生所需的输出。这只会在一行输出DB1,在另一行输出DB2。我建议的答案允许在组合元数据时具有灵活性,并将产生您要求的输出。
    • 啊,我知道当我在本地尝试时出了什么问题:当我尝试它时,我认为我的示例配置的路径是错误的。您的提供了配置的完整路径,而不仅仅是配置文件名/扩展名。
    • 哈哈哈,你的答案毕竟是浓缩的。 ;-)
    【解决方案2】:

    有一种方法可以做到这一点,只需对现有示例代码进行最少的更改。您可以将 combine metadataConfigFiles 项目和 DatabaseConfig 项目转换为新的“组合”项目,然后输出该“组合”项目。

    要合并元数据,请使用 target batching 并为每个 DatabaseConfig 项目运行一次批处理目标。然后你可以调用另一个目标来输出组合的元数据以获得你描述的输出。看看我对您的示例代码的扩展,看看这一切是如何完成的:

    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
      <ItemGroup>
        <ConfigFiles Include="*.config" />
    
        <DatabaseConfig Include="ABC">
          <Database>DB1</Database>
          <CsString>Database</CsString>
        </DatabaseConfig>
    
        <DatabaseConfig Include="DEF">
          <Database>DB2</Database>
          <CsString>Logging</CsString>
        </DatabaseConfig>
      </ItemGroup>
    
      <Target Name="test" DependsOnTargets="test_setup;test_output" >
        <!-- Logic here runs after targets listed in "DependsOnTargets". -->
      </Target>
    
      <!-- This will run once for each "DatabaseConfig" item. -->
      <Target Name="test_setup" Outputs="%(DatabaseConfig.Identity)">
        <PropertyGroup>
          <!-- Specify the Database for the current DatabaseConfig item -->
          <CurrentDb>%(DatabaseConfig.Database)</CurrentDb>
        </PropertyGroup>
        <ItemGroup>
          <!-- Add a new CombinedOutput item with each run, combining metadata. -->
          <CombinedOutput Include=" %(ConfigFiles.FileName)%(ConfigFiles.Extension) $(CurrentDb) " />
        </ItemGroup>
      </Target>
    
      <Target Name="test_output">
        <!-- Output the combined metadata from the CombinedOutput items -->
        <Message Text=" %(CombinedOutput.Identity) " />
      </Target>
    
    </Project>
    

    示例中发生了什么:

    1. test 目标现在只是用作调用其他两个目标来执行工作的一种方式:test_setuptest_output
    2. test_setup 目标被批处理并创建新的 CombinedOutput 项目。
    3. test_output 目标在 test_setup 之后调用 输出 CombinedOutput 项目的元数据。

    test_output 的输出:

    one.config DB1
    two.config DB1
    one.config DB2
    two.config DB2
    

    【讨论】:

    • 我应该更明确,我需要将两个变量分开。该消息只是为了测试,实际变量将在 XmlUpdate 步骤中使用。
    • 嗯,是的,如果能提前知道就好了。 ;-) 我的建议回答了您的原始标准,但并不专注于将这些变量分开。
    猜你喜欢
    • 2021-03-14
    • 2013-05-01
    • 1970-01-01
    • 2012-09-17
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 2011-07-20
    相关资源
    最近更新 更多