使用XSLT合并属性

时间:2016-11-02 03:02:16

标签: xml xslt msbuild

我是XSLT的绝对新手,并且在谷歌的帮助下,在过去的几个小时里拼凑了以下内容。所以要警告......

示例文件:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{C7D20737-FF45-4232-8461-34C6B5B9D1E5}</ProjectGuid>
    <PlatformToolset>v110</PlatformToolset>
  </PropertyGroup>

  <Import Project="toinline.proj" />
</Project>

toinline.proj

   <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="Stuff">
      <Stuff></Stuff>
    </Project>

基本上,我想要做的是创建一个XSLT程序,它执行一个相对简单的转换:给定一个MSBuild项目文件(它是一个XML文件),我想要内联&#39;顶级Import标记(标记使用相对路径引用文件,我想获取该文件中顶级标记的内容,并用该标记替换标记)。)

对于给定的例子,我期待像

这样的东西
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{C7D20737-FF45-4232-8461-34C6B5B9D1E5}</ProjectGuid>
    <PlatformToolset>v110</PlatformToolset>
  </PropertyGroup>

  <Stuff></Stuff>
</Project>

我已经使用了以下

<?xml version="1.0" encoding="utf-8"?>
<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 indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Replace any 'import' tag with the contents of the project file it references.
       Note that this only works with relative paths. -->
  <xsl:template match="msb:Import">
    <xsl:copy-of select="document(@Project)/msb:Project/*"/>
  </xsl:template>
</xsl:stylesheet>

现在,我遇到的问题是我内联的文件(样本中的#in; line.proj&#39;)本身有一个顶级Project标记,{{1 }}}}属性,我想要&#39;合并&#39;进入封闭文档,最终得到类似

的内容
InitialTargets

如何扩展我的解决方案呢?现在我可以假设封闭文档没有该属性,但理想情况下,如果确实如此,我们将合并内容(通过与分号连接)

1 个答案:

答案 0 :(得分:1)

声明绑定到引用文档的全局变量:

<xsl:variable name="importee" select="document(//Import/@Project)"/>

然后在现有模板规则中使用它:

<xsl:template match="msb:Import">
    <xsl:copy-of select="$importee/msb:Project/*"/>
</xsl:template>

并添加一个模板规则:

<xsl:template match="msb:Projects">
  <xsl:copy>
    <xsl:copy-of select="@*"/> 
    <xsl:attribute name="InitialTargets" select="$importee/msb:Projects/@InitiaTargets"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

PS: 我应该提到xsl:attribute/@select是XSLT 2.0语法。如果您不幸使用1.0,则需要xsl:attribute和xsl:value-of child指令。在SO帖子上,请始终说明您使用的是哪个版本,因为解决方案有时可能会有很大不同。