MsBuild XmlPeek结果分割值

时间:2014-07-23 09:13:01

标签: c# xml msbuild split

在我的MsBuild脚本(* .proj)中,我使用XmlPeek查询C#项目进行构建配置并获取PropertyGroup的Condition属性值。这是工作代码:

      <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>

这是输出:

  

&#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;

现在我需要在'=='上拆分这些内容,并且我在此处混淆了如何在拆分字符串时创建另一个ItemGroupPropertyGroup

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

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

1 个答案:

答案 0 :(得分:1)

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

我有两个解决方案:一个使用amn XslTranformation,另一个使用Exec命令。

的XslTransform

您可以使用XslTransformation任务获取构建文件,并利用substring-beforesubstring-after xslt函数对其进行转换。输出存储在一个文件中(在我的例子中为test-xslt.out),并且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>

Command Exec

此解决方案将您的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 &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)" />