0

I have a HTML file I want to parse using XSLT 1.0 the file is in the form <file name="/var/application-data/..../application/controllers/cgu.php" />

and I want it to be <file filename="cgu.php" folderName="controller/"/>

I managed to do this using <xsl:value-of select="substring-before(substring(@name, 85), '/')"/> , but I want it to work for all length of path. is it possible to count the number of occurences of "/" to retrieve only the last part of the path ?

I used a recursive template to retrieve only the filename, but I need the folder name too

<xsl:template name="substring-after-last">
        <xsl:param name="string"/>
        <xsl:choose>
            <xsl:when test="contains($string, '/')">
                <xsl:call-template name="substring-after-last">
                    <xsl:with-param name="string" select="substring-after($string, '/')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$string"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
Joël
  • 105
  • 2
  • 10
  • See: http://stackoverflow.com/questions/38848374/how-to-find-last-to-preview-work-and-store-to-my-field-in-xslt/38848925#38848925 and http://stackoverflow.com/questions/41624974/xsl-display-attribute-after-a-certain-character/41625340#41625340 – michael.hor257k May 05 '17 at 11:30

1 Answers1

0

One way to do it, is to store the results of the first call (to get the file name) in a variable, and the call the template a second time but with the name attribute truncated by the length of the file name (so that the folder name is now the last item).

<xsl:template match="file">
    <xsl:variable name="fileName">
        <xsl:call-template name="substring-after-last">
            <xsl:with-param name="string" select="@name" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="folderName">
        <xsl:call-template name="substring-after-last">
            <xsl:with-param name="string" select="substring(@name, 1, string-length(@name) - string-length($fileName) - 1)" />
        </xsl:call-template>
    </xsl:variable>
    <file filename="{$fileName}" folderName="{$folderName}/"/>
</xsl:template>

Alternatively, if your process supports it, you may be able to else EXSLT's tokenize function

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:str="http://exslt.org/strings"
    extension-element-prefixes="str">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="file">
        <xsl:variable name="parts" select="str:tokenize(@name, '/')" />
        <file filename="{$parts[last()]}" folderName="{$parts[last() - 1]}/"/>
    </xsl:template>
</xsl:stylesheet>
Tim C
  • 70,053
  • 14
  • 74
  • 93