Как разбить строку на несколько символов в MSBuild 4?

У меня есть следующая строка с именем 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 я упускаю/искажаю?


person Ian Kemp    schedule 16.01.2012    source источник


Ответы (3)


Функции свойств 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>

Или вы можете сначала создать (строковый) массив для передачи в 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 для получения дополнительной полезной информации.

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

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

  • Вы не можете получить доступ к вещам по индексу в файлах проекта 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. Как только это назначено свойству (или группе элементов), вы больше не можете этого делать.

person Christian.K    schedule 17.01.2012
comment
После того, как вы сделали это, каково содержание SplitVersion? Предположительно, это массив ITaskItem? Как мне получить доступ к значениям по отдельности, скажем, по индексу? - person Neil Barnwell; 24.01.2019

Возможно

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

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

person skolima    schedule 16.01.2012

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

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

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

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

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

person Thorsten Hans    schedule 16.01.2012
comment
Это не анализируется, поскольку у вас не может быть атрибутов Include в свойствах. - person Ian Kemp; 17.01.2012
comment
Да, правильно, это должно работать при использовании, например, ‹SplitVersion›$(MasterVersioin.Split('.','-')‹/SplitVersion› - person Thorsten Hans; 17.01.2012
comment
Нет, это не так. Во-первых, отсутствует закрывающий ')', во-вторых, посмотрите мой ответ о поддержке массивов. - person Christian.K; 19.01.2012