0

我有这样的 Msbuild XML 文件。

<?xml version="1.0" encoding="utf-8"?> 
  <Project xmlns="schemas.microsoft.com/developer/msbuild/2003">
         <ItemGroup>
             <Notifications Include="someone@gmail.com"/>
         </ItemGroup>
    <ItemGroup> 
         <Xcopy Include="..\..\..\Release\UtilitiesAssembly.dll"> 
             <Destination>"..\..\..\Mycomponent\depl\BOM\Folder1</Destination> 
         </Xcopy>
         <Xcopy Include="..\..\..\Release\Core.assembly.dll">
             <Destination>"..\..\..\Mycomponent\depl\BOM\Folder1</Destination>
         </Xcopy>
         <Xcopy Include="..\..\..\Release\UIAssembly.dll"> 
             <Destination>"..\..\..\Anothercomponent\Folder1</Destination> 
         </Xcopy>
         <Xcopy Include="..\..\..\Release\Core.assembly.dll">
             <Destination>"..\..\..\Anothercomponent\depl\BOM</Destination>
         </Xcopy>
    </Itemgroup>
  </Project>

实际上我想像这样对 XCopy Itemgroup 进行分组

      <Xcopy Include="..\..\..\Release\UtilitiesAssembly.dll;
                    ..\..\..\Release\\Core.assembly.dll;">
      <Destination>"..\..\..\Mycomponent\depl\BOM\Folder1</Destination>
     </Xcopy>

     <Xcopy Include="..\..\..\Release\UIAssembly.dll;">
      <Destination>"..\..\..\Anothercomponent\Folder1</Destination>
     </Xcopy>

     <Xcopy Include="..\..\..\Release\Core.assembly.dll">
             <Destination>"..\..\..\Anothercomponent\depl\BOM</Destination>
     </Xcopy>

如何使用 Powershell 或 Msbuild 或通过其他一些机制来实现它

4

2 回答 2

2

以下是如何使用Group-Objectcmdlet 执行此操作的示例。它将 xcopy 元素分组Destination并将Include路径组合成一个分号分隔的字符串。输出存储在一个新的 XML 文档中并保存到磁盘。这不会以编程方式更新原始文件。您可以将新合并的 XML 复制粘贴到原始 XML 上。

更新现在我看到了您的整个文件,我看到它有一个默认命名空间,这会导致 XPath 出现问题。有两种方法可以解决这个问题。

  1. 使用与命名空间无关的 xpath
  2. 使用命名空间管理器

这是一个使用与命名空间无关的 xpath 的更新示例。此外,为了获得您正在寻找的缩进,我们需要在 XML 对象处理之后进行一些文本文件处理。

$xml="Myinput.xml"
$tempXmlFile = "C:\New.xml"

$outXml = New-Object System.Xml.XmlDocument
$outXml.AppendChild($outXml.CreateElement("root")) > $null

$x = [xml] (Get-Content $xml)
$x.SelectNodes("//*[local-name()='Xcopy']") | Group-Object Destination | % {
    $includePaths = ($_.Group | Select-Object -ExpandProperty Include) -join ";"
    $element = $outXml.CreateElement("Xcopy")
    $element2 = $outXml.CreateElement("Destination")
    $element2.InnerText = $_.Name
    $element.AppendChild($element2) > $null
    $element.SetAttribute("Include", $includePaths)
    $outXml.DocumentElement.AppendChild($element) > $null
}
$outXml.Save($tempXmlFile)

$data = Get-Content $tempXmlFile | % {
    $search = 'Include="'
    $index = $_.IndexOf('Include="')
    if ($index -gt 0) { 
        $spaces = ( ' ' * ($index + $search.length) ) 
    }
    $_ -replace ';', ";`n${spaces}"
}
$data | Set-Content $tempXmlFile
& notepad $tempXmlFile

创建输出:

<root>
  <Xcopy Include="..\..\..\Release\UtilitiesAssembly.dll
                  ..\..\..\Release\Core.assembly.dll">
    <Destination>"..\..\..\Mycomponent\depl\BOM\Folder1</Destination>
  </Xcopy>
  <Xcopy Include="..\..\..\Release\UIAssembly.dll">
    <Destination>"..\..\..\Anothercomponent\Folder1</Destination>
  </Xcopy>
  <Xcopy Include="..\..\..\Release\Core.assembly.dll">
    <Destination>"..\..\..\Anothercomponent\depl\BOM</Destination>
  </Xcopy>
</root>
于 2012-01-16T09:49:09.720 回答
1

从 MSBuild 3.5 开始,您可以使用ItemDefinitionGroup

  <ItemDefinitionGroup>
    <Xcopy>
      <Destination>"..\..\..\Mycomponent\depl\BOM\Folder1</Destination>
    </Xcopy>
  </ItemDefinitionGroup>
  <ItemGroup>
    <Xcopy Include="..\..\..\Release\UtilitiesAssembly.dll" />
    <Xcopy Include="..\..\..\Release\Core.assembly.dll" />
    <Xcopy Include="..\..\..\Release\UIAssembly.dll;">
      <Destination>"..\..\..\Anothercomponent\Folder1</Destination>     
    </Xcopy>
  </ItemGroup>
于 2012-01-16T12:25:21.117 回答