No Output

1. No output problem when using a DTD
2. Output only if a test condition is true

1.

No output problem when using a DTD

David Carlisle

Q expansion

 with the following declaration
<?xml version = "1.0" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 03December 1999//EN" 
"http://www.w3.org/Graphics/SVG/SVG-19991203.dtd">

none of my templates trigger except the default ones, why?

However... when I remove the doctype line, my templates trigger quite happily.

Most likely the dtd is using an ATTLIST default to supply the namespace declaration for the root element, so when you have the dtd your source document is svg, but when you remove it is just some random unknown element in the null namespace that happens to be called `svg'. There is a big difference to an XML processor.

Look out for the associated namespace in the DTD, and declare the same namespace in the stylesheet. This one reads

<!ATTLIST svg
  xmlns CDATA 
  #FIXED 'http://www.w3.org/Graphics/SVG/SVG-19991203.dtd'

For a standalone document you need to have the namespace or namespaces (SVG also uses the XLink namespace) declared explicitly.

The templates need to check for svg in the SVG namespace, or they will find svg in the null namespace

<?xml version = "1.0" ?>
<svg xmlns="http://www.w3.org/Graphics/SVG/SVG-19991203.dtd">
and so on will do the trick.
</svg>

To fix this I now have a default template which tells me if any element is within a namespace.

  <xsl:template match="*">
       <xsl:variable name="uri">
      <xsl:choose>
        <xsl:when test="string(namespace-uri())">
          <xsl:value-of select="namespace-uri()"/>
        </xsl:when>
        <xsl:otherwise>Null Namespace</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
      
      ****   Namespace URI is: <xsl:value-of select="$uri"/>
      Declared on element: <xsl:choose>
        <xsl:when test="string(name(..))">
          <xsl:value-of select="name(..)"/>
        </xsl:when>
        <xsl:otherwise>/</xsl:otherwise>
      </xsl:choose>/<xsl:value-of select="name()"/>***
  </xsl:template>

In order to get them to trigger properly I had to add

xmlns:oeb= "http://some.url"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

as attributes to the stylesheet element, then within the templates use

<xsl:template match="oeb:doc">

2.

Output only if a test condition is true

Sara Mitchell

We are converting an XML document to another type of xml document based. Based on data discovered in the process, we do not want to do any further processing.

It sounds like one other approach that might work is simply to start your processing off based on 'ignore' not being present. This uses two templates, rather than one. Using your example, it might look something like this:

<!-- this template matches the nodes you want to ignore
     and does nothing. So it 'skips' them -->
<xsl:template match="basenode[head/tag/@action='ignore']">
</xsl:template>

<!-- this template matches all basenode nodes that aren't 
     marked to ignore -->
<xsl:template match="basenode[not(head/tag/@action='ignore')]">
<!-- do your processing -->
   <xsl:apply-templates/>
 </xsl:template>

Chris Bayes offers:

Check out <xsl:message terminate="yes"/>