I have what should be a very simple script that is essentially an
identity transform that copies a tree of DITA maps and topics from their
input location to an output location, making some modifications along
the way. (The full script is appended below.)
The input is generic DITA maps arranged in a directory structure where
each map is in its own directory. The copy needs to mirror the input
structure. I'm attempting to do this by constructing a new output
location for each new map in the tree and then passing that value as a
tunnel parameter down the apply-templates chain.
The failure I'm getting is that the tunnel value does not reflect the
value I think I'm setting it to. I may be too bleary from overwork but I
can't see anything wrong in my code so I'm at a bit of a loss as to why
this isn't working. Either I'm doing something stupid or there's a bug
in Saxon (I'm testing with Saxon 9.0.0.2J). But I normally discount the
possibility of bugs of this nature in Saxon.
Can someone tell me what stupid thing I'm doing?
Thanks,
Eliot
Here is a bit of my debug message log:
+ DEBUG: Got a topicref to something:
GAAP/Codification/Codification.ditamap
+ DEBUG:
baseOutDir="/Users/ekimber/workspace/northstar//temp/preprocess/"
+ DEBUG: TargetUrl="GAAP/Codification/Codification.ditamap"
+ DEBUG:
resultUrl="/Users/ekimber/workspace/northstar//temp/preprocess/GAAP/Codification/Codification.ditamap"
+ DEBUG:
newBase="/Users/ekimber/workspace/northstar//temp/preprocess/GAAP/Codification/"
+ DEBUG: Got a topichead: Codification
+ DEBUG:
baseOutDir="/Users/ekimber/workspace/northstar//temp/preprocess/"
+ DEBUG: Got a topicref to something:
Notice_to_Constituents/Notice_to_Constituents.ditamap
+ DEBUG:
baseOutDir="/Users/ekimber/workspace/northstar//temp/preprocess/"
+ DEBUG:
TargetUrl="Notice_to_Constituents/Notice_to_Constituents.ditamap"
+ DEBUG:
resultUrl="/Users/ekimber/workspace/northstar//temp/preprocess/Notice_to_Constituents/Notice_to_Constituents.ditamap"
+ DEBUG:
newBase="/Users/ekimber/workspace/northstar//temp/preprocess/Notice_to_Constituents/"
+ DEBUG: Got a topichead: Notice to Constituents
+ DEBUG:
baseOutDir="/Users/ekimber/workspace/northstar//temp/preprocess/"
You can see that the $newBase value correctly reflects the desired value
(it reflects the input directory of the map, e.g., the input is
GAAP/Codification and the newBase should be
/temp/preprocess/GAAP/Codification
In the template where $newBase is calculated I'm then using it to set a
new value for the tunnel parameter baseOutDir:
<xsl:template match="topicref[@href]">
<xsl:param name="baseOutDir" tunnel="yes" as="xs:string"
required="yes"/>
<xsl:variable name="targetUrl" select="@href" as="xs:string"/>
<xsl:variable name="targetDoc" select="document($targetUrl, .)"
as="document-node()?"/>
<xsl:variable name="resultUrl" select="concat($baseOutDir,
@href)" as="xs:string"/>
<xsl:variable name="pathTokens" select="tokenize($resultUrl,
'/')[position() < last()]"/>
<xsl:variable name="newBase"
select="concat(string-join($pathTokens, '/'), '/')" as="xs:string"/>
<xsl:message> + DEBUG: newBase="<xsl:value-of
select="$newBase"/>"</xsl:message>
<xsl:result-document href="{$resultUrl}">
<xsl:apply-templates select="$targetDoc">
<xsl:with-param name="baseOutDir" select="$newBase"
tunnel="yes" as="xs:string"/>
</xsl:apply-templates>
</xsl:result-document>
But as you can see from the log, baseOutDir has the same value for all
calls to the template.
Here is the full script:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<!-- This style sheet processes a tree of maps to convert topic heads
into topicrefs to title-only topics.
-->
<xsl:param name="outdir" as="xs:string" required="yes"/>
<xsl:variable name="outdirVar" select="if (ends-with($outdir, '/'))
then $outdir else concat($outdir, '/')" as="xs:string"/>
<xsl:template match="/">
<xsl:apply-templates>
<xsl:with-param name="baseOutDir" select="$outdirVar"
tunnel="yes" as="xs:string"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="topichead">
<xsl:param name="baseOutDir" tunnel="yes" as="xs:string"
required="yes"/>
<xsl:message> + DEBUG: Got a topichead: <xsl:value-of
select="@navtitle"/></xsl:message>
<xsl:message> + DEBUG: baseOutDir="<xsl:value-of
select="$baseOutDir"/>"</xsl:message>
<xsl:variable name="topicResultUrl" select="concat($baseOutDir,
'tot_', generate-id(.), '.xml')" as="xs:string"/>
<xsl:result-document href="{$topicResultUrl}">
<topic id="{concat('tot_', generate-id())}">
<title><xsl:value-of select="@navtitle"/></title>
</topic>
</xsl:result-document>
<topicref href="{$topicResultUrl}">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</topicref>
</xsl:template>
<xsl:template match="topicref[@href]">
<xsl:param name="baseOutDir" tunnel="yes" as="xs:string"
required="yes"/>
<xsl:message> + DEBUG: Got a topicref to something: <xsl:value-of
select="@href"/></xsl:message>
<xsl:message> + DEBUG: baseOutDir="<xsl:value-of
select="$baseOutDir"/>"</xsl:message>
<xsl:variable name="targetUrl" select="@href" as="xs:string"/>
<xsl:message> + DEBUG: TargetUrl="<xsl:value-of
select="$targetUrl"/>"</xsl:message>
<xsl:variable name="targetDoc" select="document($targetUrl, .)"
as="document-node()?"/>
<xsl:choose>
<xsl:when test="not($targetDoc)">
<xsl:message> + ERROR: Failed to resolve reference to map
document "<xsl:value-of select="$targetUrl"/>" from base URI
"<xsl:value-of select="base-uri(.)"/>"</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="resultUrl" select="concat($baseOutDir,
@href)" as="xs:string"/>
<xsl:message> + DEBUG: resultUrl="<xsl:value-of
select="$resultUrl"/>"</xsl:message>
<xsl:variable name="pathTokens" select="tokenize($resultUrl,
'/')[position() < last()]"/>
<xsl:variable name="newBase"
select="concat(string-join($pathTokens, '/'), '/')" as="xs:string"/>
<xsl:message> + DEBUG: newBase="<xsl:value-of
select="$newBase"/>"</xsl:message>
<xsl:result-document href="{$resultUrl}">
<xsl:apply-templates select="$targetDoc">
<xsl:with-param name="baseOutDir" select="$newBase"
tunnel="yes" as="xs:string"/>
</xsl:apply-templates>
</xsl:result-document>
</xsl:otherwise>
</xsl:choose>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
--
Eliot Kimber
Senior Solutions Architect
"Bringing Strategy, Content, and Technology Together"
Main: 610.631.6770
www.reallysi.com
www.rsuitecms.com