Search code examples
xsltnamespacesdocumentstrip

XSL: Ignoring/stripping namespaces in secondary documents


I am writing an XSL template that pulls data from many secondary sources. An example secondary document looks like this:

<toplevel xmlns:foo1="http://foo1">
 <path xmlns="http://foo1">
   <mytag>bar</mytag>
  </path>
</toplevel>

In the XSL, I am doing this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:foo1="http://foo1"
 exclude-result-prefixes="foo1">
  <xsl:variable name="secondary1" select="document('secondary1.xml')/toplevel"/>
  <foo>
    <xsl:value-of select="$secondary1//foo1:path/foo1:mytag"/>
  </foo>
</xsl:stylesheet>

With a lot of secondary sources, each of which uses a different namespace, prefixing every single tag is tedious, and that much repetition can't be the right thing to do anyway. Is there a way to use document() such that the namespace of the imported node-set is stripped (or to achieve the same effect another way)?


Solution

  • In essence, a node with a namespace is an entirely different animal than a node with another namespace - even if they happen to share the same local name. (This is much the same way namespaces work everywhere else - there is really no easy way of "ignoring" namespaces. Think of ignoring namespaces when referring to classes in C#.)

    The clean approach would be to mention each namespace you might encounter in the XSLT and work with prefixes, even if it seems repetitive.

    The not-so-clean way is this:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
      <xsl:variable name="secondary1" select="document('secondary1.xml')"/>
    
      <xsl:template match="/">
        <foo source="1">
          <xsl:value-of select="
            $secondary1//*[local-name() = 'path']/*[local-name() = 'mytag']
          "/>
        </foo>
      </xsl:template>
    </xsl:stylesheet>
    

    This is not really more pleasing to the eye than working with prefixes, it's longer and harder to read, it is ambiguous, and last but not least - it is slower because the engine must test a predicate on every step on the XPath. Take your pick.