Hints

Here are some hints, how the XSLT scripts should be modified. All these examples are taken from an XSLT transformer with XSL-FO result - feel free to modify these snippets for your result document appropriately.

First, you must define GENE namespace, of course. Just put this definition into root element of XSLT:

xmlns:gene="dom://baka.sk/xml/gene" xmlns:gpar="dom://baka.sk/xml/gene/param"

Use the following template to handle generef processing instructions:

<!-- makes a copy of the generef processing instruction -->
 <xsl:template match="processing-instruction('generef')">
   <xsl:copy-of select="."/>
 </xsl:template>

You may safely ignore processing these elements if schema doesn't support inserting elements from another namespaces.

This template prints out the ID of node(s):

<!-- Prints ID of given node. -->
<xsl:template match="@*" mode="gene.getId" priority="1">
  <xsl:if test="../@gene:id">
    <xsl:value-of select="../@gene:id"/><xsl:text>@</xsl:text><xsl:value-of select="name()"/>,0
  </xsl:if>
</xsl:template>
<xsl:template match="*" mode="gene.getId" priority="1">
  <xsl:value-of select="@gene:id"/>,0
</xsl:template>
<xsl:template match="node()" mode="gene.getId" priority="0">
  <xsl:if test="../@gene:id">
    <xsl:value-of select="../@gene:id"/>;<xsl:value-of select="count(preceding-sibling::node())"/>,0
  </xsl:if>
</xsl:template>

Note that the ,0 part is optional and may not be used at all. You may parametrize the template to put an arbitrary string there, to differentiate same IDs if needed. This step is optional: XSLT/exporter and/or coordinator must be able to uniqualize gene:ids if they need unique ids.

To instantiate attribute containing ID of given node, the following snippet can be used: (note that this attribute is instantiated only when the gene:id attribute exists - it is useful for XSLT to be usable both with and without GENE)

<!-- Instantiates an id attribute for given node. -->
<xsl:template match="*" mode="gene.createIdAttr" priority="1">
  <xsl:if test="@gene:id">
    <xsl:attribute name="gene:id"><xsl:apply-templates select="." mode="gene.getId"/></xsl:attribute>
  </xsl:if>
</xsl:template>
<xsl:template match="node() | @*" mode="gene.createIdAttr" priority="0">
  <xsl:if test="../@gene:id and $gpar:processingSource">
    <xsl:attribute name="gene:id"><xsl:apply-templates select="." mode="gene.getId"/></xsl:attribute>
  </xsl:if>
</xsl:template>

<xsl:value-of select="<nodeset>"/> works OK, if you don't want to transport IDs of text. If you do, use <xsl:apply-templates select="<nodeset>" mode="gene.printTextWithIds"> instead, and put following template into your XSLT script:

<!-- Prints text value of given node with proper IDs, as if by the <xsl:value-of/> call. -->
<xsl:template match="*" mode="gene.printTextWithIds">
  <xsl:apply-templates mode="gene.printTextWithIds"/>
</xsl:template>
<xsl:template match="text()" mode="gene.printTextWithIds">
  <xsl:choose>
    <xsl:when test="../@gene:id and $gpar:processingSource">
      <fo:inline>
        <xsl:apply-templates select="." mode="gene.createIdAttr"/>
        <xsl:value-of select="."/>
      </fo:inline>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="."/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Easiest way to auto-transfer IDs of text is to define this template:

<!-- retains ids of all text nodes -->
<xsl:template match="text()">
  <apply-templates select="." mode="gene.printTextWithIds"/>
</xsl:template>

Because each element may contain the gene:id attribute, we must replace all XPath tests such as @* with the following test:

@*[name()!='gene:id']

To detect whether the ID of context node is synthetic or not please use this boolean expression:

contains(substring-before(@gene:id, ','), '@;')