tags:

views:

172

answers:

1

DocBook XSL includes a template that matches all element

<xsl:template match="*">
  <xsl:message> ....  </xsl:message>
</xsl:template>

I need to override it with another template because my source XML tree contains more that just the DoocBook XML. If I specify such a template in the file it overrides all templates in DocBook XSL. It seems like that all imported templates, are prioritized on the order of import only, and NOT according to how specific the template is.

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:db="http://docbook.org/ns/docbook" version="1.0">

  <xsl:import href="docbook-xsl-ns/xhtml/docbook.xsl" />
  <xsl:import href="copy.xsl"/>

  <xsl:template match="/">
    <xsl:apply-templates select="//db:book"/>
  </xsl:template>
</xsl:stylesheet>

copy.xsl

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform&gt;

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
        <!-- go process attributes and children -->
        <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Sample XML source

<?xml version="1.0" encoding="UTF-8"?>
<root>
<http-host>localhost</http-host>
<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"  xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:svg="http://www.w3.org/2000/svg" xmlns:m="http://www.w3.org/1998/Math/MathML" xml:id="course.528" xml:lang="en" version="5.0">
  <info>
   <title>Postoperative Complications</title>    
  </info>
  <chapter xml:id="chapter.1">
   <title>INTRODUCTION</title>
   <para>Postoperative complications are a constant threat to the millions  ....</para>
  </chapter>
</book>
<errors></errors>
</root>

This is true for both Xalan and xsltproc processors. How do I override this template without having to change the DocBook XSL source. I tried messing with priorities but that did not work.

+1  A: 

From what I understand, you want to apply the copy.xsl's template only for non-docbook elements. Try to be more specific in your copy.xsl - by being more specific in your copy.xsl, that template will get selected for all non-docbook elements.

copy.xsl

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform&gt;

  <xsl:template match="*[not(namespace-uri() = 'http://docbook.org/ns/docbook')]"&gt;
    <xsl:element name="{local-name()}">
        <!-- go process attributes and children -->
        <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Depending on the presence of DocBook elements within non-Docbook nodes, you might need to restrict the nodeset for which you apply at the apply-templates part as well(based on the namespace) and maybe mess around the apply-templates flow to make sure it handles it predictably. Hope this is of some use to you..

Thiyagaraj
This is more of a work around, but I think this will work in my case; all of DocBook element are together, the rest are custom elements from local namespace.Still, why more specific templates imported before general template do not get applied. The general template imported later overrides them all. Is there a way to override that behavior? If I am to do that with priorities, is there a way to see what the priorities are at the time of the import?
xsaero00