在我的MsBuild脚本(* .proj)中,我使用XmlPeek查询C#项目进行构建配置并获取PropertyGroup
的Condition属性值。这是工作代码:
<Target Name="xPeek">
<XmlPeek Namespaces="<Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>"
XmlInputPath=" D:\source\MyProject.csproj"
Query="/msb:Project/msb:PropertyGroup[contains(@Condition,'Debug')]/@Condition">
<Output TaskParameter="Result" ItemName="Peeked" />
</XmlPeek>
<Message Text="%(Peeked.Identity)" />
</Target>
这是输出:
&#39;发布| AnyCPU&#39; ==&#39;调试| AnyCPU&#39;
&#39;发布| AnyCPU&#39; ==&#39; Debug.v9 | AnyCPU&#39;
&#39;发布| AnyCPU&#39; ==&#39; Debug.v10 | AnyCPU&#39;
&#39;发布| AnyCPU&#39; ==&#39; Debug.v101 | AnyCPU&#39;
现在我需要在'=='
上拆分这些内容,并且我在此处混淆了如何在拆分字符串时创建另一个ItemGroup
或PropertyGroup
。
%(Peeked.Identity).Split('==')
什么都不做。
问题1 :如何在拆分所有值时使用此ItemGroup
上的拆分?
问题2 :此外,是否可以从XmlPeek中使用的XQuery中获取分割值?
答案 0 :(得分:1)
XmlPeek任务不允许执行addiontinal Xslt函数。不幸的是,msbuild中没有内置字符串函数。
我有两个解决方案:一个使用amn XslTranformation,另一个使用Exec命令。
您可以使用XslTransformation任务获取构建文件,并利用substring-before和substring-after xslt函数对其进行转换。输出存储在一个文件中(在我的例子中为test-xslt.out),并且ReadLinesfromFile读取并转换为Items。
有一点需要注意:在这种情况下,变量不会被替换,而对于XmlPeek,变量不会被替换。
safexml编码版本如下所示:
<XslTransformation XmlInputPaths = "test-xslttrans.csproj"
XslContent="
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msb="http://schemas.microsoft.com/developer/msbuild/2003"
>
<xsl:output method="text" indent="yes" />
<xsl:template match="text()|@*"/>
<xsl:template match="/msb:Project/msb:PropertyGroup[contains(@Condition,'Debug')]">
<xsl:value-of select="substring-before(@Condition,'==')"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="substring-after(@Condition,'==')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet> "
OutputPaths = "test-xslt.out">
</XslTransformation>
<ReadLinesFromFile
File="test-xslt.out" >
<Output
TaskParameter="Lines"
ItemName="SplittedPeek"/>
</ReadLinesFromFile>
<Message Text="%(SplittedPeek.Identity)" />
为方便起见,这是普通的xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msb="http://schemas.microsoft.com/developer/msbuild/2003">
<xsl:output method="text" indent="yes" />
<xsl:template match="text()|@*"/>
<xsl:template match="/msb:Project/msb:PropertyGroup[contains(@Condition,'Debug')]" >
<xsl:value-of select="substring-before(@Condition,'==')"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="substring-after(@Condition,'==')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
此解决方案将您的Peeked值写入文件。通过调用命令处理器的FOR / F commamnd,我们可以解析行并在一些严格的边界内将它们拆分,这在这里很合适。 EXEC的输出被写入文件split.txt。 ReadLinesFromFiles用于读取Item中的值。
<WriteLinesToFile
File="test-xslt-write.out"
Lines="@(Peeked)"
Overwrite="true"
Encoding="ASCII"/>
<Exec Command="for /f "tokens=1* delims==" %%a in (test-xslt-write.out) do @echo %%a > split.txt"/>
<Exec Command="for /f "tokens=1* delims==" %%a in (test-xslt-write.out) do @echo %%b >> split.txt"/>
<ReadLinesFromFile
File="test-xslt.out" >
<Output
TaskParameter="Lines"
ItemName="SplittedCmdPeek"/>
</ReadLinesFromFile>
<Message Text="%(SplittedCmdPeek.Identity)" />