J. G.
J. G.

Reputation: 1832

XSL namespace issues when transforming to an SVG file

I'm making a simple SVG file from some alto xml files. I have it working except for an annoying namespace issue.

The header for the source xml (which I shouldn't change) is

    <alto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.loc.gov/standards/alto/ns-v2#" 
    xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v2# http://www.loc.gov/standards/alto/alto-v2.0.xsd" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    >

and the header for my xsl (which I'd be delighted to change if we can fix this)

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/2000/svg"
   >

These two things combined created the saxon error:

Severity: warning Description: SXXP0005: The source document is in namespace http://www.loc.gov/standards/alto/ns-v2#, but all the template rules match elements in no namespace URL: http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/trans/SaxonErrorCode.html#SXXP0005

If I delete the line xmlns="http://www.loc.gov/standards/alto/ns-v2#" from the source my transformation works perfectly... but I don't want to have to modify and unmodify hundreds of these files just to get this script working. So I really need a change that will fix the xsl. I've tried adding the alto line to the xsl sheet, but that just gives an "already has a namespace" error.

Upvotes: 2

Views: 510

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167716

Well you haven't shown us any of your templates and the Saxon warning is about templates but I think you want to use

<xsl:stylesheet version="2.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/2000/svg"
   xpath-default-namespace="http://www.loc.gov/standards/alto/ns-v2#"
   >

Upvotes: 0

Ian Roberts
Ian Roberts

Reputation: 122414

As the warning message suggests, all the elements in your source XML are in the http://www.loc.gov/standards/alto/ns-v2# namespace, so you need to bind this namespace to a prefix in your stylesheet:

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:a="http://www.loc.gov/standards/alto/ns-v2#"
   >

and then use the prefix in your template rules and XPath expressions, e.g. instead of /alto/foo/bar you'd use /a:alto/a:foo/a:bar. In an XSLT 1.0 stylesheet this is the only way to match elements that are in a namespace, but since you say you're using Saxon you could switch your stylesheet to XSLT 2.0 and use xpath-default-namespace to avoid having to prefix everything everywhere:

<xsl:stylesheet version="2.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns="http://www.w3.org/2000/svg"
   xpath-default-namespace="http://www.loc.gov/standards/alto/ns-v2#"
   >

With this in place, paths like /alto will match elements in the relevant namespace.

Upvotes: 1

Related Questions