Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

encode-for-uri and absolute Windows paths

I've got an XML file that contains sections that start with a filename:

<madcapfile filename="C:\1\Outputpath\The 7% solution.xlf">

Each section must be saved to an individual file. This is my XSLT:

<xsl:template match="madcapfile">
  <xsl:variable name="file1" select="concat('file:///',@filename)"/>
  <xsl:variable name="file2" select="encode-for-uri($file1)"/>
  <xsl:variable name="file3" select="concat('file:///',replace(@filename,'%','%25'))"/>
  <xsl:result-document method="xml" href="{$file2}">  
    <xsl:apply-templates select="node()"/>
  </xsl:result-document>
</xsl:template>

The variables file1, file2, file3 are my attempts so far. Variable file1 creates files in the correct locations for all files except those with a % in the filename.
Variable file3 creates files in the correct locations for all files, so this is a working solution.

Using variable file2 gives an error: the XSLT processor (Saxon 9.7) tries to write files to

C:\Path-to-XSLT\C:\1\Outputpath\The 7% solution.xlf  

i.e. it looks like encode-for-uri treats its input as a relative path even though it starts with "C:\"
I've also tried adding "file:///" to the start of the path, that does not change the behavior of encode-for-uri.

Is there a way to force encode-for-uri to treat its input as an absolute path?

like image 590
Hobbes Avatar asked Mar 04 '26 20:03

Hobbes


2 Answers

There are two issues, the href attributes expects a URI and in a URI the separator character is / and not \ which is used in Windows file paths. Furthermore the use of encode-for-uri escapes any backslash.

So to solve the problem you should replace any backward slash with a forwards slash, then you can use encode-for-uri to escape the percent sign:

concat('file:///', encode-for-uri(replace(@filename, '\\', '/')))
like image 200
Martin Honnen Avatar answered Mar 07 '26 09:03

Martin Honnen


On the specific question:

Is there a way to force encode-for-uri to treat its input as an absolute path?

The spec says of fn:encode-for-uri:

Encodes reserved characters in a string that is intended to be used in the path segment of a URI.

So the answer is no: that's not what the function is for. It's not designed to process complete URIs or to understand their syntax; it's designed to process a string that is to be used in constructing the path segment of a URI.

like image 40
Michael Kay Avatar answered Mar 07 '26 10:03

Michael Kay