xsl-list
[Top] [All Lists]

Re: [xsl] XSLT 2.0 compability issue occured in topicmerge.XSL in DITA 1.5.1

2012-06-19 05:14:09
Hi Michael,
I have just overcome the error by modifying the xml:lang to read xmllang.

This does fix the issue, however, Saxon invokes  error Fatal Error! An
attribute node (role) cannot be created after the children of the
containing element once again.

Thanks
Ray



2012/6/19, team wise <dfanster(_at_)gmail(_dot_)com>:
Hi Michael,

Further to my last message, I just run another version of the
problematic XSLT 1.0 stylesheet which I reported to the list and got
this error:

  [xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:47:31:
Fatal Error! Variable name is not a valid QName: xml:lang
  [xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:120:45:
Fatal Error! Variable name is not a valid QName: xml:lang
  [xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:174:56:
Fatal Error! XPath syntax error at char 23 on line 174 in
{string-length($xml:lang) >}:
  [xslt]     Variable $xml:lang has not been declared
  [xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:176:47:
Fatal Error! XPath syntax error at char 9 on line 176 in {$xml:lang}:
  [xslt]     Variable $xml:lang has not been declared

I have refactored a bit the XSLT 1.0 stylesheet and made it XSLT 2.0 as
follows:


<?xml version="1.0" encoding="UTF-8" ?>
<!-- This file is part of the DITA Open Toolkit project hosted on
     Sourceforge.net. See the accompanying license.txt file for
     applicable licenses.-->
<!-- (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved. -->

<!-- book.xsl
 | Merge DITA topics with "validation" of topic property
 *-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="2.0">

<!-- Import error message template -->
<xsl:import href="common/output-message.xsl"/>

<!-- SEMC 2009-08-03: Added for S60 help text output -->
<xsl:import href="InfoShare/common/infoshare.params.xsl"/>
<xsl:import href="InfoShare/common/infoshare.jobticket.xsl"/>
<xsl:import href="InfoShare/common/infoshare.filesystem.xsl"/>
<xsl:import href="InfoShare/common/infoshare.internationalization.xsl"/>
<xsl:param name="OUTPUTDIR"/>
<xsl:param name="WORKDIR"/>
<xsl:param name="sub-merge" select="'false'"/>

<!-- Set the prefix for error message numbers -->
<xsl:variable name="msgprefix">DOTX</xsl:variable>

<xsl:variable name="xml-path"/>

<xsl:output method="xml" encoding="utf-8"/>

<xsl:template match="/*">
   <xsl:element name="{name()}">
     <xsl:apply-templates select="@*" mode="copy-element"/>
     <xsl:apply-templates />
   </xsl:element>
</xsl:template>

<xsl:template match="/*/*[contains(@class,' map/topicmeta ')]"
priority="1">
  <xsl:apply-templates select="." mode="copy-element"/>
</xsl:template>
<xsl:template match="*[contains(@class,' map/topicmeta ')]"/>
<xsl:template match="*[contains(@class,' map/navref ')]"/>
<xsl:template match="*[contains(@class,' map/reltable ')]"/>
<xsl:template match="*[contains(@class,' map/anchor ')]"/>

<xsl:template match="*[contains(@class,' map/topicref
')][@href][not(@href='')][not(@print='no')]">
  <xsl:param name="xml:lang"/>
  <xsl:param name="ditamap-language"/>
  <xsl:variable name="topicrefClass"><xsl:value-of
select="@class"/></xsl:variable>
  <!--xsl:comment>Start of embed for <xsl:value-of
select="@href"/></xsl:comment-->

  <xsl:variable name="ish">
    <xsl:value-of select="/processing-instruction('ish')[.]"/>
  </xsl:variable>
  <xsl:variable name="language-code">
    <xsl:value-of select="substring-before(substring-after($ish,
'lang=&quot;'), '&quot;')"/>
  </xsl:variable>

  <xsl:variable name="href">
    <xsl:choose>
      <xsl:when test="string-length($ditamap-language) &gt; 0">
        <xsl:choose>
          <xsl:when test="($multilingual = 'yes') and ($outputformat =
'UG_A7_Print')">
            <xsl:value-of select="concat($ditamap-language, '/', @href)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@href"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:when test="string-length($language-code) &gt; 0">
        <xsl:choose>
          <xsl:when test="($multilingual = 'yes') and ($outputformat =
'UG_A7_Print')">
            <xsl:value-of select="concat($language-code, '/', @href)"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@href"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@href"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:comment>Start of embed for <xsl:value-of
select="$href"/></xsl:comment>

  <!-- SEMC 2010-05-20: Added to check if file exists -->
  <xsl:variable name="topic-exists">
    <xsl:call-template name="file-exists">
      <xsl:with-param name="filename" select="concat($WORKDIR,
'\temp\', $href)"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <!-- Topicref to non-dita files will be ingored in PDF transformation
-->
    <xsl:when test="@format and not(@format='dita' or @format='ditamap')">
      <xsl:call-template name="output-message">
        <xsl:with-param name="msgnum">049</xsl:with-param>
        <xsl:with-param name="msgsev">I</xsl:with-param>
      </xsl:call-template>
    </xsl:when>
    <!-- SEMC 2009-05-20: Added this test for sub maps in a map -->
    <xsl:when test="$topic-exists = 'false'">
      <xsl:choose>
        <!-- S60 sub maps in a map -->
        <xsl:when test="$sub-merge = 'true'">
          <xsl:variable name="navtitle" select="@navtitle"/>
          <xsl:result-document href="{$OUTPUTDIR}/{$navtitle}/merged.xml">
            <xsl:apply-templates
select="document(concat(substring-before(@href, '.xml'),
'.ditamap'),/)"/>
          </xsl:result-document>
        </xsl:when>
        <!-- S60 help texts -->
        <xsl:when test="$outputformat = 'HTML_S60'">
          <xsl:apply-templates
select="document(concat(substring-before(@href, '.xml'),
'.ditamap'),/)//*[contains(@class,' map/topicref ')]"/>
        </xsl:when>
        <!-- Sub maps in a map for a non-S60 publication -->
        <xsl:otherwise>
          <xsl:apply-templates
select="document(concat(substring-before(@href, '.xml'),
'.ditamap'),/)/*[contains(@class,' map/map ')]/*[contains(@class,'-
map/topicref ')]">
            <xsl:with-param name="xml:lang">
              <xsl:choose>
                <xsl:when test="@xml:lang"><xsl:value-of
select="@xml:lang"/></xsl:when>
                <xsl:otherwise/>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="ditamap-language">
              <xsl:choose>
                <xsl:when test="$multilingual = 'yes'">
                  <xsl:variable name="temp">
                    <xsl:value-of
select="document(concat(substring-before(@href, '.xml'),
'.ditamap'),/)/processing-instruction('ish')[.]"/>
                  </xsl:variable>
                  <xsl:value-of
select="substring-before(substring-after($temp, 'lang=&quot;'),
'&quot;')"/>
                </xsl:when>
                <xsl:otherwise/>
              </xsl:choose>
            </xsl:with-param>
          </xsl:apply-templates>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:when test="contains(@href,'#')">
      <xsl:variable name="sourcefile"><xsl:value-of
select="substring-before(@href,'#')"/></xsl:variable>
      <xsl:variable name="sourcetopic"><xsl:value-of
select="substring-after(@href,'#')"/></xsl:variable>
      <xsl:variable name="targetName"><xsl:value-of
select="name(document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1])"/></xsl:variable>
      <xsl:if test="$targetName and not($targetName='')">
      <xsl:element name="{$targetName}">
        <xsl:apply-templates
select="document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1]/@*" mode="copy-element"/>
        <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
        <xsl:apply-templates
select="document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1]/*" mode="copy-element">
          <xsl:with-param name="src-file"><xsl:value-of
select="$sourcefile"/></xsl:with-param>
        </xsl:apply-templates>
        <xsl:apply-templates/>
      </xsl:element>
      </xsl:if>
    </xsl:when>
    <!-- If the target is a topic, as opposed to a ditabase mixed file -->
    <xsl:when test="document(@href,/)/*[contains(@class,' topic/topic ')]">
      <xsl:variable name="targetName"><xsl:value-of
select="name(document(@href,/)/*)"/></xsl:variable>
      <xsl:if test="$targetName and not($targetName='')">
      <xsl:element name="{$targetName}">
        <xsl:apply-templates select="document(@href,/)/*/@*"
mode="copy-element"/>
        <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
        <!-- If the root element of the topic does not contain an id
attribute, then generate one.
             Later, we will use these id attributes as anchors for PDF
bookmarks. -->
        <xsl:if test="not(document(@href,/)/*/@id)">
          <xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
        </xsl:if>
        <!-- For multilingual UG_A7_Print -->
        <xsl:if test="@xml:lang">
          <xsl:attribute name="only-for-language">
            <xsl:value-of select="@xml:lang"/>
          </xsl:attribute>
        </xsl:if>
        <xsl:if test="string-length($xml:lang) &gt; 0">
          <xsl:attribute name="only-for-language">
            <xsl:value-of select="$xml:lang"/>
          </xsl:attribute>
        </xsl:if>
        <xsl:apply-templates select="document(@href,/)/*/*"
mode="copy-element">
          <xsl:with-param name="src-file"><xsl:value-of
select="@href"/></xsl:with-param>
        </xsl:apply-templates>
        <xsl:apply-templates/>
      </xsl:element>
      </xsl:if>
    </xsl:when>
    <!-- Otherwise: pointing to ditabase container; output each topic
in the ditabase file.
         The refclass value is copied to each of the main topics.
         If this topicref has children, they will be treated as
children of the <dita> wrapper.
         This is the same as saving them as peers of the topics in the
ditabase file. -->
    <xsl:otherwise>
      <xsl:for-each select="document(@href,/)/*/*">
        <xsl:element name="{name()}">
          <xsl:apply-templates select="@*" mode="copy-element"/>
          <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
          <xsl:apply-templates select="*" mode="copy-element"/>
        </xsl:element>
      </xsl:for-each>
      <xsl:apply-templates/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="*[contains(@class,' map/topicref ')][not(@href)]">
  <xsl:element name="{name()}">
    <xsl:apply-templates select="@*" mode="copy-element"/>
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="*|@*|comment()|processing-instruction()|text()"
mode="copy-element">
      <xsl:param name="src-file"></xsl:param>
  <xsl:copy>
    <xsl:apply-templates
select="*|@*|comment()|processing-instruction()|text()"
mode="copy-element">
      <xsl:with-param name="src-file"><xsl:value-of
select="$src-file"/></xsl:with-param>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="processing-instruction()" >
  <xsl:copy />
</xsl:template>
<!--
  <xsl:template match="@id" mode="copy-element">
    <xsl:attribute name="id"><xsl:value-of
select="generate-id(.)"/></xsl:attribute>
  </xsl:template>
-->
<xsl:template match="@href" mode="copy-element" priority="1">
  <xsl:param name="src-file"></xsl:param>

  <xsl:variable name="file-path">
    <xsl:call-template name="get-file-path">
      <xsl:with-param name="src-file">
        <xsl:value-of select="$src-file"/>
      </xsl:with-param>
    </xsl:call-template>
    <xsl:value-of select="."/>
  </xsl:variable>

  <xsl:variable name="file-path-new">
    <xsl:call-template name="normalize-path">
      <xsl:with-param name="file-path">
        <xsl:value-of select="translate($file-path,'\','/')"/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="contains(.,'://') or ../@scope='external' or
../@scope='peer'">
      <xsl:copy/>
    </xsl:when>
    <xsl:when test="(parent::*[contains(@class,' topic/xref ')] or
parent::*[contains(@class,' topic/link ')]) and (not(../@format) or
../@format='dita' or ../@format='DITA')">
      <xsl:choose>
        <xsl:when test="starts-with(.,'#')">
          <xsl:variable name="refer-path" select="substring-after(.,'#')"/>
          <xsl:choose>
            <xsl:when test="contains($refer-path,'/')">
              <xsl:variable name="topic-id"
select="substring-before($refer-path,'/')"/>
              <xsl:variable name="target-id"
select="substring-after($refer-path,'/')"/>
              <xsl:variable name="href-value">
                <xsl:value-of select="//*[contains(@class,'
topic/topic ')][@id=$topic-id]//*[@id=$target-id]/@id"/>
              </xsl:variable>
              <xsl:if test="not($href-value='')">
                <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
              </xsl:if>
            </xsl:when>
            <xsl:otherwise>
              <xsl:variable name="href-value">
                <xsl:value-of select="//*[contains(@class,'
topic/topic ')][@id=$refer-path]/@id"/>
              </xsl:variable>
              <xsl:if test="not($href-value='')">
                <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
              </xsl:if>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:when test="contains(.,'#')">
          <xsl:variable name="file-name" select="substring-before(.,'#')"/>
          <xsl:variable name="refer-path" select="substring-after(.,'#')"/>
          <xsl:variable name="file-name-doc"
select="document($file-name,/)"/>
          <xsl:if test="$file-name-doc and not($file-name-doc='')">
          <xsl:choose>
            <xsl:when test="contains($refer-path,'/')">
              <xsl:variable name="topic-id"
select="substring-before($refer-path,'/')"/>
              <xsl:variable name="target-id"
select="substring-after($refer-path,'/')"/>
              <xsl:variable name="href-value">
                <xsl:value-of
select="$file-name-doc//*[contains(@class,' topic/topic
')][@id=$topic-id]//*[@id=$target-id]/@id"/>
              </xsl:variable>
              <xsl:if test="not($href-value='')">
                <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
              </xsl:if>
            </xsl:when>
            <xsl:otherwise>
              <xsl:variable name="href-value">
                <xsl:value-of
select="$file-name-doc//*[contains(@class,' topic/topic
')][@id=$refer-path]/@id"/>
              </xsl:variable>
              <xsl:if test="not($href-value='')">
                <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
              </xsl:if>
            </xsl:otherwise>
          </xsl:choose>
          </xsl:if>
        </xsl:when>
        <xsl:otherwise>
          <xsl:variable name="current-doc" select="document(.,/)"/>
          <xsl:if test="$current-doc and not($current-doc='')">
          <xsl:choose>
            <xsl:when test="$current-doc//*[contains(@class,'
topic/topic ')]/@id">
              <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$current-doc//*[contains(@class,' topic/topic
')][1]/@id"/></xsl:attribute>
            </xsl:when>
            <xsl:otherwise><xsl:text>#</xsl:text><xsl:value-of
select="$current-doc//*[contains(@class,' topic/topic
')][1]"/></xsl:otherwise>
          </xsl:choose>
          </xsl:if>
        </xsl:otherwise>
      </xsl:choose>

    </xsl:when>
    <xsl:otherwise>
      <xsl:attribute name="href">
        <xsl:value-of select="$file-path-new"/>
      </xsl:attribute>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="get-file-path">
  <xsl:param name="src-file"/>
  <xsl:if test="contains($src-file,'/')">
    <xsl:value-of select="substring-before($src-file,'/')"/>
    <xsl:text>/</xsl:text>
    <xsl:call-template name="get-file-path">
      <xsl:with-param name="src-file">
        <xsl:value-of select="substring-after($src-file,'/')"/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template name="normalize-path">
        <xsl:param name="file-path" />
        <xsl:choose>
            <xsl:when test="contains($file-path,'..')">
                <xsl:variable name="firstdir"
select="substring-before($file-path, '/')" />
                <xsl:variable name="newpath"
select="substring-after($file-path,'/')" />
                <xsl:choose>
                    <xsl:when test="$firstdir='..'">
                        <xsl:text>../</xsl:text>
                        <xsl:call-template name="normalize-path">
                            <xsl:with-param name="file-path">
                                <xsl:value-of select="$newpath"/>
                            </xsl:with-param>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:variable name="beforedotdot"
select="substring-before($file-path,'/..')"></xsl:variable>
                        <xsl:variable name="beforedotdotparent" >
                            <xsl:call-template name="parent-path">
                                <xsl:with-param name="pathname"
select="$beforedotdot" />
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:variable name="afterdotdot"
select="substring-after($file-path,'../')"></xsl:variable>
                        <xsl:call-template name="normalize-path">
                            <xsl:with-param name="file-path">
                                <xsl:value-of
select="concat($beforedotdotparent,$afterdotdot)"/>
                            </xsl:with-param>
                        </xsl:call-template>
                    </xsl:otherwise>
                 </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$file-path"></xsl:value-of>
            </xsl:otherwise>
        </xsl:choose>
 </xsl:template>
      
      <xsl:template name="parent-path">
        <xsl:param name="pathname" />
        <xsl:choose>
            <xsl:when test="contains($pathname, '/')">
                <xsl:value-of select="substring-before($pathname, '/')"/>
                <xsl:text>/</xsl:text>
                <xsl:call-template name="parent-path">
                    <xsl:with-param name="pathname"
select="substring-after($pathname,'/')"/>
                </xsl:call-template>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Please could you advise what is wrong with <xsl:param name="xml:lang"/>?

Cheers,

2012/6/19, team wise <dfanster(_at_)gmail(_dot_)com>:
Hi Michael,
Many thanks for your prompt response. You are right that XSLT 1.0
surpresses the error message or it is recoverable.

I have a favor to ask what kind of a running sample would be desirable
for you to spot the error.
I have tried replacing the line <xsl:variable
name="topicrefClass"><xsl:value-of select="@class"/></xsl:variable>
with this line <xsl:variable name="topicrefClass"
select="string(@class)"/> , but made no difference.

I grealty appeciate your time again.

2012/6/19, Michael Kay <mike(_at_)saxonica(_dot_)com>:


On 19/06/2012 07:25, team wise wrote:
Hi there,
When dealing with a XSL style sheet transition to XSLT 2.0, I just
encountered with this following error message:

  [xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:112:
Fatal Error! An attribute node (id) cannot be created after the
children of the containing element ( I just commented out line 112 and
subsequent lines).
[xslt]
D:\InfoShare\AppSOMC\Utilities\DITA-OT\SEMC_Infoshare\xsl\topicmerge.xsl:120:
Fatal Error! An attribute node (id) cannot be created after the
children of the containing element
This is a "recoverable error" in XSLT 1.0: processors are allowed to
recover by ignoring the attribute. But they aren't required to recover,
they can also treat it as fatal. In XSLT 2.0 the WG decided to improve
interoperability by making it a hard error, so all processors must
report it.

Despite trying to reconstitute your stylesheet with the original line
numbers, I haven't been able to spot where the code is wrong. There
should be a Saxon stack trace giving more detail of the call stack at
the point of failure; alternatively running with -T will give you output
that is voluminous but very informative. I'm happy to help debug it if
you can provide a runnable sample.

In general the fix is to make sure you always output the attributes of
an element before outputting its child nodes.

I noticed, incidentally, that the stylesheet is making liberal use of
this kind of construct:

<xsl:variable name="topicrefClass"><xsl:value-of
select="@class"/></xsl:variable>

when it should be doing

<xsl:variable name="topicrefClass" select="string(@class)"/>

Saxon does its best to optimize this, but it can only do so when it's
possible to analyze all uses of the variable to ensure that the variable
is always used as a string. When this isn't possible, you incur the high
cost of constructing a temporary tree to hold the value, which is a very
heavyweight data structure compared with a single string. I've seen
stylesheets speeded up by a factor of 5 by fixing this problem.

Michael Kay
Saxonica

There are a couple of threads over the Internet that are related to
the error ,  for example, Michael commented on a similar problem,
however, I am bitter at my wit ends to work out a solution that works
in this context.

We implement Saxon 9. stylesheet is written in XSLT 1.0 as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- This file is part of the DITA Open Toolkit project hosted on
      Sourceforge.net. See the accompanying license.txt file for
      applicable licenses.-->

<!-- book.xsl
  | Merge DITA topics with "validation" of topic property
  *-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<!-- Include error message template -->
<xsl:import href="common/output-message.xsl"/>
<!-- Set the prefix for error message numbers -->
<xsl:variable name="msgprefix">DOTX</xsl:variable>

<xsl:variable name="xml-path"></xsl:variable>

<xsl:output method="xml" encoding="utf-8" />

<xsl:template match="/*">
    <xsl:element name="{name()}">
      <xsl:apply-templates select="@*" mode="copy-element"/>
      <xsl:apply-templates select="*"/>
    </xsl:element>
</xsl:template>

<xsl:template match="/*/*[contains(@class,' map/topicmeta ')]"
priority="1">
   <xsl:apply-templates select="." mode="copy-element"/>
</xsl:template>

<xsl:template match="/*[contains(@class,' map/map
')]/*[contains(@class,' topic/title ')]">
   <xsl:apply-templates select="." mode="copy-element"/>
</xsl:template>

<xsl:template match="*[contains(@class,' map/topicmeta ')]"/>
<xsl:template match="*[contains(@class,' map/navref ')]"/>
<xsl:template match="*[contains(@class,' map/reltable ')]"/>
<xsl:template match="*[contains(@class,' map/anchor ')]"/>

<xsl:template match="*[contains(@class,' map/topicref
')][@href][not(@href='')][not(@print='no')]">
   <xsl:variable name="topicrefClass"><xsl:value-of
select="@class"/></xsl:variable>
   <xsl:comment>Start of imbed for<xsl:value-of
select="@href"/></xsl:comment>
   <xsl:choose>
     <xsl:when test="@format and not(@format='dita')">
        <!-- Topicref to non-dita files will be ingored in PDF
transformation -->
       <xsl:call-template name="output-message">
         <xsl:with-param name="msgnum">049</xsl:with-param>
         <xsl:with-param name="msgsev">I</xsl:with-param>
       </xsl:call-template>
     </xsl:when>
     <xsl:when test="contains(@href,'#')">
       <xsl:variable name="sourcefile"><xsl:value-of
select="substring-before(@href,'#')"/></xsl:variable>
       <xsl:variable name="sourcetopic"><xsl:value-of
select="substring-after(@href,'#')"/></xsl:variable>
       <xsl:variable name="targetName"><xsl:value-of
select="name(document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1])"/></xsl:variable>
       <xsl:if test="$targetName and not($targetName='')">
       <xsl:element name="{$targetName}">
         <xsl:apply-templates
select="document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1]/@*" mode="copy-element"/>
         <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
         <xsl:apply-templates
select="document($sourcefile,/)//*[@id=$sourcetopic][contains(@class,'
topic/topic ')][1]/*" mode="copy-element">
           <xsl:with-param name="src-file"><xsl:value-of
select="$sourcefile"/></xsl:with-param>
         </xsl:apply-templates>
         <xsl:apply-templates/>
       </xsl:element>
       </xsl:if>
     </xsl:when>
     <!-- If the target is a topic, as opposed to a ditabase mixed file
-->
     <xsl:when test="document(@href,/)/*[contains(@class,' topic/topic
')]">
       <xsl:variable name="targetName"><xsl:value-of
select="name(document(@href,/)/*)"/></xsl:variable>
       <xsl:if test="$targetName and not($targetName='')">
       <xsl:element name="{$targetName}">
         <xsl:apply-templates select="document(@href,/)/*/@*"
mode="copy-element"/>
         <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
         <!-- If the root element of the topic does not contain an id
attribute, then generate one.
              Later, we will use these id attributes as anchors for PDF
bookmarks. -->
         <xsl:if test="not(document(@href,/)/*/@id)">
           <xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
         </xsl:if>
         <xsl:apply-templates select="document(@href,/)/*/*"
mode="copy-element">
           <xsl:with-param name="src-file"><xsl:value-of
select="@href"/></xsl:with-param>
         </xsl:apply-templates>
         <xsl:apply-templates/>
       </xsl:element>
       </xsl:if>
     </xsl:when>
     <!-- Otherwise: pointing to ditabase container; output each topic
in the ditabase file.
          The refclass value is copied to each of the main topics.
          If this topicref has children, they will be treated as
children of the<dita>  wrapper.
          This is the same as saving them as peers of the topics in the
ditabase file. -->
     <xsl:otherwise>
       <xsl:for-each select="document(@href,/)/*/*">
         <xsl:element name="{name()}">
           <xsl:apply-templates select="@*" mode="copy-element"/>
           <xsl:attribute name="refclass"><xsl:value-of
select="$topicrefClass"/></xsl:attribute>
           <xsl:apply-templates select="*" mode="copy-element"/>
         </xsl:element>
       </xsl:for-each>
       <xsl:apply-templates/>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

<xsl:template match="*[contains(@class,' map/topicref ')][not(@href)]">
   <xsl:element name="{name()}">
     <xsl:apply-templates select="@*" mode="copy-element"/>
     <xsl:apply-templates/>
   </xsl:element>
</xsl:template>

<!--xsl:template
match="*|@*|comment()|processing-instruction()|text()"
mode="copy-element">
<xsl:param name="src-file"></xsl:param>
   <xsl:copy>
     <xsl:apply-templates
select="*|@*|comment()|processing-instruction()|text()"
mode="copy-element">
       <xsl:with-param name="src-file"><xsl:value-of
select="$src-file"/></xsl:with-param>
     </xsl:apply-templates>
   </xsl:copy>
</xsl:template-->

   <xsl:template match="@id" mode="copy-element">
     <xsl:attribute name="id"><xsl:value-of
select="generate-id(.)"/></xsl:attribute>
   </xsl:template>

<xsl:template match="@href" mode="copy-element" priority="1">
   <xsl:param name="src-file"></xsl:param>

   <xsl:variable name="file-path">
     <xsl:call-template name="get-file-path">
       <xsl:with-param name="src-file">
         <xsl:value-of select="$src-file"/>
       </xsl:with-param>
     </xsl:call-template>
     <xsl:value-of select="."/>
   </xsl:variable>

   <xsl:variable name="file-path-new">
     <xsl:call-template name="normalize-path">
       <xsl:with-param name="file-path">
         <xsl:value-of select="translate($file-path,'\','/')"/>
       </xsl:with-param>
     </xsl:call-template>
   </xsl:variable>

   <xsl:choose>
     <xsl:when test="contains(.,'://') or ../@scope='external' or
../@scope='peer'">
       <xsl:copy/>
     </xsl:when>
     <xsl:when test="(parent::*[contains(@class,' topic/xref ')] or
parent::*[contains(@class,' topic/link ')]) and (not(../@format) or
../@format='dita' or ../@format='DITA')">
       <xsl:choose>
         <xsl:when test="starts-with(.,'#')">
           <xsl:variable name="refer-path"
select="substring-after(.,'#')"/>
           <xsl:choose>
             <xsl:when test="contains($refer-path,'/')">
               <xsl:variable name="topic-id"
select="substring-before($refer-path,'/')"/>
               <xsl:variable name="target-id"
select="substring-after($refer-path,'/')"/>
               <xsl:variable name="href-value">
                 <xsl:value-of
select="generate-id(//*[contains(@class,' topic/topic
')][@id=$topic-id]//*[@id=$target-id]/@id)"/>
               </xsl:variable>
               <xsl:if test="not($href-value='')">
                 <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
               </xsl:if>
             </xsl:when>
             <xsl:otherwise>
               <xsl:variable name="href-value">
                 <xsl:value-of
select="generate-id(//*[contains(@class,' topic/topic
')][@id=$refer-path]/@id)"/>
               </xsl:variable>
               <xsl:if test="not($href-value='')">
                 <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
               </xsl:if>
             </xsl:otherwise>
           </xsl:choose>
         </xsl:when>
         <xsl:when test="contains(.,'#')">
           <xsl:variable name="file-name"
select="substring-before(.,'#')"/>
           <xsl:variable name="refer-path"
select="substring-after(.,'#')"/>
           <xsl:variable name="file-name-doc"
select="document($file-name,/)"/>
           <xsl:if test="$file-name-doc and not($file-name-doc='')">
           <xsl:choose>
             <xsl:when test="contains($refer-path,'/')">
               <xsl:variable name="topic-id"
select="substring-before($refer-path,'/')"/>
               <xsl:variable name="target-id"
select="substring-after($refer-path,'/')"/>
               <xsl:variable name="href-value">
                 <xsl:value-of
select="generate-id($file-name-doc//*[contains(@class,' topic/topic
')][@id=$topic-id]//*[@id=$target-id]/@id)"/>
               </xsl:variable>
               <xsl:if test="not($href-value='')">
                 <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
               </xsl:if>
             </xsl:when>
             <xsl:otherwise>
               <xsl:variable name="href-value">
                 <xsl:value-of
select="generate-id($file-name-doc//*[contains(@class,' topic/topic
')][@id=$refer-path]/@id)"/>
               </xsl:variable>
               <xsl:if test="not($href-value='')">
                 <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="$href-value"/></xsl:attribute>
               </xsl:if>
             </xsl:otherwise>
           </xsl:choose>
           </xsl:if>
         </xsl:when>
         <xsl:otherwise>
           <xsl:variable name="current-doc" select="document(.,/)"/>
           <xsl:if test="$current-doc and not($current-doc='')">
           <xsl:choose>
             <xsl:when test="$current-doc//*[contains(@class,'
topic/topic ')]/@id">
               <xsl:attribute
name="href"><xsl:text>#</xsl:text><xsl:value-of
select="generate-id($current-doc//*[contains(@class,' topic/topic
')][1]/@id)"/></xsl:attribute>
             </xsl:when>
             <xsl:otherwise><xsl:text>#</xsl:text><xsl:value-of
select="generate-id($current-doc//*[contains(@class,' topic/topic
')][1])"/></xsl:otherwise>
           </xsl:choose>
           </xsl:if>
         </xsl:otherwise>
       </xsl:choose>

     </xsl:when>
     <xsl:otherwise>
       <xsl:attribute name="href">
         <xsl:value-of select="$file-path-new"/>
       </xsl:attribute>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

<xsl:template name="get-file-path">
   <xsl:param name="src-file"/>
   <xsl:if test="contains($src-file,'/')">
     <xsl:value-of select="substring-before($src-file,'/')"/>
     <xsl:text>/</xsl:text>
     <xsl:call-template name="get-file-path">
       <xsl:with-param name="src-file">
         <xsl:value-of select="substring-after($src-file,'/')"/>
       </xsl:with-param>
     </xsl:call-template>
   </xsl:if>
</xsl:template>

<xsl:template name="normalize-path">
         <xsl:param name="file-path" />
         <xsl:choose>
             <xsl:when test="contains($file-path,'..')">
                 <xsl:variable name="firstdir"
select="substring-before($file-path, '/')" />
                 <xsl:variable name="newpath"
select="substring-after($file-path,'/')" />
                 <xsl:choose>
                     <xsl:when test="$firstdir='..'">
                         <xsl:text>../</xsl:text>
                         <xsl:call-template name="normalize-path">
                             <xsl:with-param name="file-path">
                                 <xsl:value-of select="$newpath"/>
                             </xsl:with-param>
                         </xsl:call-template>
                     </xsl:when>
                     <xsl:otherwise>
                         <xsl:variable name="beforedotdot"
select="substring-before($file-path,'/..')"></xsl:variable>
                         <xsl:variable name="beforedotdotparent">
                             <xsl:call-template name="parent-path">
                                 <xsl:with-param name="pathname"
select="$beforedotdot" />
                             </xsl:call-template>
                         </xsl:variable>
                         <xsl:variable name="afterdotdot"
select="substring-after($file-path,'../')"></xsl:variable>
                         <xsl:call-template name="normalize-path">
                             <xsl:with-param name="file-path">
                                 <xsl:value-of
select="concat($beforedotdotparent,$afterdotdot)"/>
                             </xsl:with-param>
                         </xsl:call-template>
                     </xsl:otherwise>
                  </xsl:choose>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:value-of select="$file-path"></xsl:value-of>
             </xsl:otherwise>
         </xsl:choose>
  </xsl:template>
   
   <xsl:template name="parent-path">
         <xsl:param name="pathname" />
         <xsl:choose>
             <xsl:when test="contains($pathname, '/')">
                 <xsl:value-of select="substring-before($pathname,
'/')"/>
                 <xsl:text>/</xsl:text>
                 <xsl:call-template name="parent-path">
                     <xsl:with-param name="pathname"
select="substring-after($pathname,'/')"/>
                 </xsl:call-template>
             </xsl:when>
         </xsl:choose>
     </xsl:template>

   <xsl:template match="processing-instruction()">
     <xsl:copy></xsl:copy>
   </xsl:template>

</xsl:stylesheet>

Are there anyone out there who had similar experience before? How did
you manage to overcome it?

Thank you in advance
Ray

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or 
e-mail:<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--
Keep an Exacting Eye for Detail



--
Keep an Exacting Eye for Detail



-- 
Keep an Exacting Eye for Detail

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--