Как объединить в один атрибут, если метаданные одинаковы? - PullRequest
0 голосов
/ 16 января 2012

У меня 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 или другой механизм

Ответы [ 2 ]

2 голосов
/ 16 января 2012

Вот пример того, как это сделать с помощью командлета Group-Object.Он сгруппирует элементы 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>
1 голос
/ 16 января 2012

Начиная с 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>
...