【问题标题】:XSLT: Blank values after transformationXSLT:转换后的空白值
【发布时间】:2019-12-05 17:30:25
【问题描述】:

我正在尝试进行 xsl 转换:文件 Id="" KeyPath="yes" Source="" 有 Id 和 Source 空白。我关注了其他文章并修复了命名空间,但仍然没有结果。

原始文件:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Component Id="cmpF22D40156F8E16FBFA89C752FF9D0EF9" Guid="{965AF45C-4B87-44B9-A881-7BEB4CB8D1E1}">
                <File Id="fil2DACDED111D2125FD9BAF52808E5CEB0" KeyPath="yes" Source="$(var.BasePath)\api-ms-win-core-console-l1-1-0.dll" />
            </Component>
<Component Id="cmpCEE39BB900F45E2F684F712DD10CEF09" Guid="{FA583F14-6375-42BE-9BB0-046FB8DCB0D1}">
                <File Id="fil51FD07FBBBA9CBF4E0ABE1A9AD93D19C" KeyPath="yes" Source="$(var.BasePath)\Api.exe" />
            </Component>
        </ComponentGroup>
     </DirectoryRef>
    </Fragment>
</Wix>

输出:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Component Id="cmpF22D40156F8E16FBFA89C752FF9D0EF9" Guid="{965AF45C-4B87-44B9-A881-7BEB4CB8D1E1}">
                <File Id="fil2DACDED111D2125FD9BAF52808E5CEB0" KeyPath="yes" Source="$(var.BasePath)\api-ms-win-core-console-l1-1-0.dll" />
            </Component>
      <Component Id="cmpCEE39BB900F45E2F684F712DD10CEF09" Guid="{FA583F14-6375-42BE-9BB0-046FB8DCB0D1}"><File Id="" KeyPath="yes" Source="" />
      </Component>
  </ComponentGroup>
    </DirectoryRef>
    </Fragment>
</Wix>

XSL 文件:

<xsl:stylesheet version="2.0" xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:x="http://www.w3.org/2005/Atom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:param name="InstallFolder"/>
  <xsl:param name="DisplayName"/>
  <xsl:param name="Name"/>
  <xsl:param name="Description"/>

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

  <!-- Set Directory Reference to INSTALLFOLDER (set if required) -->
  <xsl:template match="wix:DirectoryRef/@Id">
    <xsl:attribute name="Id">
      <xsl:value-of select="$InstallFolder"/>
    </xsl:attribute>
  </xsl:template>

  <!-- XSL Template to inject WiX service installation elements to a .wxs generated from Heat Project task -->
  <!-- There may be other ways to look for your file -->
  <xsl:template match='wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Component[wix:File[@Source="$(var.BasePath)\Api.exe"]]'>

    <xsl:element name="Component">      
      <xsl:attribute name="Id">
        <xsl:value-of select="@Id"/>
      </xsl:attribute>
      <xsl:attribute name="Guid">
        <xsl:value-of select="@Guid"/>
      </xsl:attribute>

      <xsl:element name="File">
        <xsl:attribute name="Id">
          <xsl:value-of select="File/@Id"/>
        </xsl:attribute>
        <xsl:attribute name="KeyPath">yes</xsl:attribute>
        <xsl:attribute name="Source">
          <xsl:value-of select="File/@Source"/>
        </xsl:attribute>

      </xsl:element>
      <xsl:element name="ServiceInstall">
    <!-- Service Install -->
    <xsl:attribute name="Id">SERVICEINSTALLER</xsl:attribute>
    <xsl:attribute name="DisplayName">
      <xsl:value-of select="$DisplayName"/>
    </xsl:attribute>
    <xsl:attribute name="Name">
      <xsl:value-of select="$Name"/>
    </xsl:attribute>
    <xsl:attribute name="Description">
      <xsl:value-of select="$Description"/>
    </xsl:attribute>
    <xsl:attribute name="Start">auto</xsl:attribute>
    <xsl:attribute name="Account">LocalSystem</xsl:attribute>
    <xsl:attribute name="Type">ownProcess</xsl:attribute>
    <xsl:attribute name="ErrorControl">normal</xsl:attribute>
    <xsl:attribute name="Vital">yes</xsl:attribute>

  </xsl:element>
  <!-- Service Control, set as required -->
  <xsl:element name="ServiceControl">
    <xsl:attribute name="Id">SERVICECONTROLLER</xsl:attribute>
    <xsl:attribute name="Name">
      <xsl:value-of select="$Name"/>
    </xsl:attribute>
    <xsl:attribute name="Remove">uninstall</xsl:attribute>
    <xsl:attribute name="Stop">both</xsl:attribute>
    <xsl:attribute name="Start">install</xsl:attribute>
  </xsl:element>
    </xsl:element>       
  </xsl:template>

</xsl:stylesheet>

【问题讨论】:

  • 您的 XML 格式不正确:&lt;DirectoryRef Id="INSTALLFOLDER"&gt;&lt;/ComponentGroup&gt; 不匹配。
  • 那么,您得到的是一个组件文件节点的结果,而不是第二个组件文件节点的结果?
  • @DaniAya 是的,正确
  • @michael.hor257k 我可能错过了。真实文件有很多。与值为 "$(var.BasePath)\MircomApi.exe" 的 Source 匹配的那个会生成具有空 Id 和 Source 的 File

标签: xml xslt


【解决方案1】:

您创建元素的方法太复杂了。不要使用&lt;xsl:element&gt;除非您打算动态计算元素名称。

对于具有固定名称的元素,写出该元素。我还缩短了匹配表达式,似乎不需要this特定,并引入了属性值模板。

您的基本错误是它不是File,而是wix:File

<xsl:template match='wix:Component[wix:File[@Source="$(var.BasePath)\MircomApi.exe"]]'>
  <Component Id="{@Id}" Guid="{@Guid}">
    <File Id="{wix:File/@Id}" Source="{wix:File/@Source}" KeyPath="yes" />
  </Component>
</xsl:template>

再看看你的样本,我相信你实际上想要复制元素,除了当它们不满足你的条件时。

通过为要删除的元素编写一个空模板并为其他所有内容使用标识模板,这更容易完成。注意最后一个模板。

<xsl:stylesheet version="2.0" xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:x="http://www.w3.org/2005/Atom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:param name="InstallFolder"/>
  <xsl:param name="DisplayName"/>
  <xsl:param name="Name"/>
  <xsl:param name="Description"/>

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

  <!-- Set Directory Reference to INSTALLFOLDER (set if required) -->
  <xsl:template match="wix:DirectoryRef/@Id">
    <xsl:attribute name="Id">
      <xsl:value-of select="$InstallFolder"/>
    </xsl:attribute>
  </xsl:template>

  <!-- any wix:Component that's NOT a match will be suppressed from the output -->
  <xsl:template match='wix:Component[not(wix:File[@Source="$(var.BasePath)\MircomApi.exe"])]' />
</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    相关资源
    最近更新 更多