Как разбить строку на несколько символов в MSBuild 4? - PullRequest
10 голосов
/ 16 января 2012

У меня есть следующая строка с именем MasterVersion:

1.1-SNAPSHOT

Мне нужно разделить его по. и - так он становится массивом string[], называемым SplitVersion, т.е.

1
1
SNAPSHOT

Я перепробовал все, что мог придумать, включая около десятка вариантов ниже, без радости:

<!-- doesn't work -->
<ItemGroup>
    <VersionDelimiters Include="." />
    <VersionDelimiters Include="-" />
    <SplitVersion Include="$(MasterVersion.Split(@VersionDelimiters))" />
</ItemGroup>

<!-- doesn't work either -->
<ItemGroup>
    <SplitVersion Include="$(MasterVersion.Split([`.`; `-`]))" />
</ItemGroup>

Какой неясный синтаксис MSBuild я пропустил / испортил?

Ответы [ 3 ]

13 голосов
/ 17 января 2012

Функции свойств MSBuild 4.0 не могут обрабатывать массивы (ну в основном), однако, когда вы делаете

Split(`,`, `-`)

Вы вызываете перегрузку String.Split(params string[]), для которой требуется массив (даже в C # ключевое слово params создаст массив позади сцены и выполнит что-то вроде Split(new string[] { ',', '-' }) внутри).

Вы могли бы сделать следующее:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
 ToolsVersion="4.0">

    <PropertyGroup>
        <MasterVersion>1.1-SNAPSHOT</MasterVersion>
    </PropertyGroup>

    <ItemGroup>
        <SplitVersion Include="$(MasterVersion.Replace(`-`, `.`).Split(`.`))" />
    </ItemGroup>

    <Target Name="Test">
        <Message Importance="high" Text="@(SplitVersion)"/>
    </Target>
</Project>

Или вы можете сначала создать массив (string) для передачи в Split:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    <PropertyGroup>
        <MasterVersion>1.1-SNAPSHOT</MasterVersion>
        <Delimiters>.;-</Delimiters>
        <DelimitersArray>$(Delimiters.Split(`;`))</DelimitersArray>
    </PropertyGroup>
    <ItemGroup>
        <SplitVersion Include="$(MasterVersion.Split($(DelimitersArray)))" />
    </ItemGroup>
    <Target Name="Test">
        <Message Importance="high" Text="@(SplitVersion)"/>
    </Target>
</Project>

Что не очень лучше в этом случае; -)

О, и вы можете проверить этот блог MSDN y для получения дополнительной информации.

Обновление для комментария:

  • «Содержимое» SplitVersion технически является «массивом ITaskItem», да. Вы будете иметь дело с этим, однако вы будете иметь дело с Предметами (из ItemGroups); включая такие вещи, как «пакетирование» и т. д.

  • Вы действительно не можете «получить доступ к индексам» в файлах проекта msbuild. Выражения как $(SplitVersion)[0] или @(SplitVersion)[0] или @(SplitVersion[0]) не делай то, что думаешь / любишь. Если бы вы действительно могли бы назначить свойства для элементов массива по индексу.

Пример:

<PropertyGroup>
  <SplitVersion0>$(MasterVersion.Split($(DelimitersArray))[0])</SplitVersion0>
  <SplitVersion1>$(MasterVersion.Split($(DelimitersArray))[1])</SplitVersion1>
  <SplitVersion2>$(MasterVersion.Split($(DelimitersArray))[2])</SplitVersion2>
</PropertyGroup>

Здесь работает оператор индексирования массива, потому что в этом случае вы все еще «в контексте» выражения .NET. Как только это будет присвоено свойству (или группе товаров), вы больше не сможете этого делать.

0 голосов
/ 17 января 2012

Вы используете это выражение в ItemGroup, ItemGroups используются для сбора необходимых артефактов для сборки.Я думаю, что вы ищете PropertyGroup

Что-то вроде этого

<PropertyGroup>
  <MasterVersion>1.1-SNAPSHOT</MasterVersion>
  <SplitVersion Include="$(MasterVersion.Split(`.`,`-`)" />
</PropertyGroup>

Вы должны помнить, что на свойства ссылаются в MSBuild с помощью $ (знак доллара).На элементы ссылаются с помощью @ (at Sign).

В зависимости от группы MasterVersion, вы должны изменить $ на @

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

Возможно

<ItemGroup>
    <SplitVersion Include="$(MasterVersion.Split('.','-'))" />
</ItemGroup>

(MSBuild должен автоматически преобразовать это в массив)

...