0

I am an XSLT 1.0 newbie. In a string element in my XML, I want to change the directory parts of the path of a jar file (C:\abc\my.jar) to a static string and retain the jar file name ($PATH_VAR$\my.jar).

The original XML snippet looks like:

<object class="someclass">
   <property name="path">
      <string><![CDATA[C:\abc\my.jar]]></string>
   </property>
</object>

and I want the transformed XML to be:

<object class="someclass">
   <property name="path">
      <string><![CDATA[$PATH_VAR$\my.jar]]></string>
   </property>
</object>

Note that the original path can be any length (\\xyz\abc or Z:\abc\def\ghi), and the jar file can be named anything.

I'm not sure how to parse the original path string and change only the directories part of it. Please help!

-Jeff

Jeff M
  • 1
  • 2
  • 1
    "*change only the parent path part*" Isn't *parent part* the part before the first `"\"` ? That would make your result `"$PATH_VAR$\abc\my.jar"`, wouldn't it? -- P.S. Please indicate XSLT 1.0 or 2.0. – michael.hor257k Jul 27 '15 at 20:08
  • By parent I mean up to "\my.jar." I am currently using XSLT 2.0. – Jeff M Jul 27 '15 at 20:31
  • I removed references to parent path to -- hopefully -- avoid confusion. – Jeff M Jul 27 '15 at 20:45

2 Answers2

1

Extracting only the file name - i.e. the part after the last \ separator - is easy in XSLT 2.0:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="string"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="string/text()">
    <xsl:text>$PATH_VAR$\</xsl:text>
    <xsl:value-of select="tokenize(., '\\')[last()]"/>
</xsl:template>

</xsl:stylesheet>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
1

This is xslt 1.0. But looks like you are using xslt 2.0 so it's useless =)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" cdata-section-elements="string"/>

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

    <xsl:template match="string/text()">
        <xsl:choose>
            <xsl:when test="substring-after(., '\')">
                <xsl:call-template name="process">
                    <xsl:with-param name="left" select="."/>
                </xsl:call-template>
            </xsl:when>
            <!-- no slash == no $PATH_VAR$ -->
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="process">
        <xsl:param name="left"/>

        <xsl:choose>
            <!-- if we have at least one slash ahead - cut everything before first slash and call template recursively -->
            <xsl:when test="substring-after($left, '\')">
                <xsl:call-template name="process">
                    <xsl:with-param name="left" select="substring-after($left, '\')"/>
                </xsl:call-template>
            </xsl:when>
            <!-- if there are no slashes ahead then we have only file name left, that's all -->
            <xsl:otherwise>
                <xsl:value-of select="concat('$PATH_VAR$\', $left)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
Rudolf Yurgenson
  • 603
  • 6
  • 12
  • 'I am currently using XSLT 2.0' v.s. 'I just read another post and found out I really am using XLST 1.0' - My head will explode now :) – Rudolf Yurgenson Jul 28 '15 at 16:01