MsBuild XmlPeek结果拆分值

本文关键字:拆分 结果 XmlPeek MsBuild | 更新日期: 2023-09-27 18:14:14

在我的MsBuild脚本(*.proj)中,我正在使用XmlPeek查询c#项目的构建配置,并获得PropertyGroup的条件属性的值。下面是工作代码:

      <Target Name="xPeek">
    <XmlPeek Namespaces="&lt;Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;"
             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>

输出:

'Release |AnyCPU' == 'Debug|AnyCPU'
"释放|AnyCPU"=="调试"。v9 | AnyCPU '
"释放|AnyCPU"=="调试"。v10 | AnyCPU '
'Release |AnyCPU' == 'Debug.v101|AnyCPU'

现在我需要在'=='上分割这些,我在这里感到困惑,如何在分割字符串的同时创建另一个ItemGroupPropertyGroup

%(Peeked.Identity).Split('==')什么都不做

问题1:如何在此ItemGroup上使用Split,同时分割其所有值?
问题2:此外,是否有可能从XmlPeek中使用的XQuery中获得拆分值?

MsBuild XmlPeek结果拆分值

XmlPeek任务不允许执行额外的Xslt函数。不幸的是,在msbuild中没有内置字符串函数。

我有两个解决方案为您:一个与一个xsltransform和一个与一个命令的执行。

XslTransform

您可以使用XslTransformation任务获取构建文件,并利用substring-before和substring-after xslt函数对其运行转换。输出存储在一个文件(test-xslt)中。读取ReadLinesfromFile并将其转换为Items。

有一点需要注意:在这个场景中,变量不会被替换,而在XmlPeek场景中,变量会被替换。

safexml编码的版本如下所示:

   <XslTransformation XmlInputPaths = "test-xslttrans.csproj"
      XslContent="
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
    xmlns:msb=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;
&gt;
   &lt;xsl:output method=&quot;text&quot; indent=&quot;yes&quot; /&gt;
  &lt;xsl:template match=&quot;text()|@*&quot;/&gt;
  &lt;xsl:template match=&quot;/msb:Project/msb:PropertyGroup[contains(@Condition,'Debug')]&quot;&gt;
&lt;xsl:value-of select=&quot;substring-before(@Condition,'==')&quot;/&gt;
&lt;xsl:text&gt;
&lt;/xsl:text&gt;
&lt;xsl:value-of select=&quot;substring-after(@Condition,'==')&quot;/&gt;
&lt;xsl:text&gt;
&lt;/xsl:text&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;   "
      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>
命令执行

此解决方案将您的窥视值写入文件。通过调用命令处理器的FOR/F命令,我们可以解析行并将它们划分为一些严格的边界,这很适合这里。EXEC的输出被写入文件split.txt。ReadLinesFromFiles用于读取Item中的值。

 <WriteLinesToFile
          File="test-xslt-write.out"
          Lines="@(Peeked)"
          Overwrite="true"
          Encoding="ASCII"/>
 <Exec Command="for /f &quot;tokens=1* delims==&quot; %%a in (test-xslt-write.out) do @echo %%a > split.txt"/>
 <Exec Command="for /f &quot;tokens=1* delims==&quot; %%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)" />