I'm using MSBuild extension pack to replace lines in .proj files. I'm replacing multiple lines with multiple lines. The lines it's outputting still have a semi colon at the end even when I do a transform.
<ItemGroup>
<TestFile Include="regextest.xml" />
<MyLines Include ="%3CItemGroup%3E%0A"/>
<MyLines Include ="%09%3CReference Include=%22Stuff%22%3E%0A" />
<MyLines Include ="%09%09%3CHintPath%3E..\..\packages\secret.dll%3C/HintPath%3E%0A" />
<MyLines Include ="%09%09%3CPrivate%3ETrue%3C/Private%3E%0A" />
<MyLines Include ="%09%3C/Reference%3E%0A" />
<MyLines Include ="%3C/ItemGroup%3E%0A" />
</ItemGroup>
<Target Name="Default">
<MSBuild.ExtensionPack.FileSystem.File TaskAction="Replace"
TextEncoding="ASCII"
RegexPattern="%3CProjectReference"
RegexOptionList="IgnoreCase"
Replacement="@(MyLines->'%(Identity)')"
Files="@(TestFile)" />
</Target>
And this is the output:
<ItemGroup>
; <Reference Include="Stuff">
; <HintPath>..\..\packages\secret.dll</HintPath>
; <Private>True</Private>
; </Reference>
;</ItemGroup>
Doing it without the transform still has them there too.
One easy way to handle multi-line replacement strings is to form them in a CDATA
block inside of a property instead of a collection of single-line items (this is where the semicolons come from). In this case, you could create the multi-line replacement string as a property and then assign its value to an item, then pass the item to the Replace
task action:
<PropertyGroup>
<MyMultiLine>
<![CDATA[
%3CItemGroup%3E
%3CReference Include="Stuff"%3E
%3CHintPath%3E..\..\packages\secret.dll%3C/HintPath%3E
%3CPrivate>True%3C/Private%3E
%3C/Reference%3E
%3C/ItemGroup%3E
]]>
</MyMultiLine>
</PropertyGroup>
<ItemGroup>
<TestFile Include="regextest.xml" />
<MyMultiLineItem Include="$(MyMultiLine)" />
</ItemGroup>
<Target Name="Default">
<MSBuild.ExtensionPack.FileSystem.File TaskAction="Replace"
TextEncoding="ASCII"
RegexPattern="%3CProjectReference"
RegexOptionList="IgnoreCase"
Replacement="@(MyMultiLineItem ->'%(Identity)')"
Files="@(TestFile)" />
</Target>