0

I'm a very beginner in XSLT. I use heat.exe from Wix toolset to generate payloads.

Here is example 1 of generated xml:

<PayloadGroup Id="ALC_272_662_888">
    <Payload SourceFile="$(var.SourceDir4)\VISTA\WAVESGUILIB.DLL" Name="$(var.SourceDir4)\VISTA\WAVESGUILIB.DLL" />
    <Payload SourceFile="$(var.SourceDir4)\VISTA\WAVESLIB.DLL" Name="$(var.SourceDir4)\VISTA\WAVESLIB.DLL" />
</PayloadGroup>

This is example 2:

<PayloadGroup Id="CS_H81_Q87">
    <Payload SourceFile="$(var.SourceDir1)\CSVER.DLL" Name="$(var.SourceDir1)\CSVER.DLL" />
    <Payload SourceFile="$(var.SourceDir1)\DIFXAPI.DLL" Name="$(var.SourceDir1)\DIFXAPI.DLL" />
    <Payload SourceFile="$(var.SourceDir1)\HELP.TXT" Name="$(var.SourceDir1)\HELP.TXT" />
    <Payload SourceFile="$(var.SourceDir1)\IIF2.INI" Name="$(var.SourceDir1)\IIF2.INI" />
</PayloadGroup>

I would like to create ONE transformation which will replace in attribute Name text $(var.SourceDir1) or $(var.SourceDir4) with empty string depending on which one will be present.

I tried multiple things - but xslt has it's own logic. Thank you in advance!

Vinoth Krishnan
  • 2,925
  • 6
  • 29
  • 34
sloter1024
  • 21
  • 2
  • 1
    It's always best to show us one thing that you tried, and that didn't work. That gives us an idea of how far up the learning curve you are, and helps to show that you've made an effort before asking for help. It's also important with XSLT questions to indicate whether you're using XSLT 1.0 or 2.0, since both are in common use and the solutions are often very different. – Michael Kay Mar 23 '16 at 07:44
  • I used modified version of this transformation: http://stackoverflow.com/a/33834345/5587125 where i duplicated template with var.SourceDir1 instead var.SourceDir. – sloter1024 Mar 23 '16 at 14:35

1 Answers1

0

This would do the trick:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

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

 <xsl:template match="@Name[contains(current(),'var.SourceDir4)') or contains(current(),'var.SourceDir1)')]">
  <xsl:attribute name="Name">
   <xsl:value-of select="substring-after(current(),')')"/>       
  </xsl:attribute>
 </xsl:template>
</xsl:transform>

The first template (match="@*|node()") makes an exact copy of everything. The second template overrides any attribute with name of 'Name' that contains either 'var.SourceDir4)' or 'var.SourceDir1)' in it's value and replaces the attribute value with whatever comes after the first closing ')'.

EDIT#1: Added fiddle for clarification: http://xsltransform.net/bnnZX2

EDIT#2: It works with 'current()' with the engine 'Saxon 9.5.1.6 HE'. With 'Saxon 9.5.1.6 EE', 'Saxon 6.5.5' or 'Xalan 2.7.1' you need to use '.' instead of 'current()', to make it work.

Sune S.-T.
  • 235
  • 2
  • 15
  • Thank you for this answer - i'll definetely try it. Is there any way to modify this transform to do this trick? http://stackoverflow.com/a/33834345/5587125 – sloter1024 Mar 23 '16 at 14:47
  • I tried it and i'm getting error: The 'current()' function cannot be used in a pattern – sloter1024 Mar 23 '16 at 15:05
  • Strange. It works for me. Try replacing 'current()' with '.' (context node) – Sune S.-T. Mar 23 '16 at 15:10
  • See the fiddle attached to the question. It works with current() with Saxon 9.5.1.6 HE. In Saxon 9.5.1.6 EE, Saxon 6.5.5 and Xalan 2.7.1 you need to use '.' instead of 'current()' – Sune S.-T. Mar 23 '16 at 15:24