2

I use XSLT as a "code generator" for various components, including other XSLT. For example, I have a query that produces an XML output of MSSQL sys.columns rows for a table, and wish to produce an XSLT that includes a table with a column for each row.

So I want to produce the following XSLT:

<xsl:stylesheet version="1.0" xmlns:format="urn:qbo3-formatting" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  ...
</xsl:stylesheet>

I generate the XSLT above with something like this 'generator' XSLT:

<xsl:element name="xsl:stylesheet">
  <xsl:attribute name="version">1.0</xsl:attribute>
  <xsl:attribute name="format" namespace="http://www.w3.org/XML/1998/namespace" >urn:qbo3-formatting</xsl:attribute>
  ...
</xsl:element>

The problem is that this 'generator' XSLT produces:

<xsl:stylesheet version="1.0" xml:format="urn:qbo3-formatting" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  ...
</xsl:stylesheet>

Note the xml:format instead of the desired xmlns:format.

According to W3C, 'xmlns' is reserved and bound to 'http://www.w3.org/2000/xmlns/'. If I attempt to create the format attribute above using this namespace, I get an error:

Elements and attributes cannot belong to the reserved namespace 'http://www.w3.org/2000/xmlns/'.

Any suggestions on a work-around?

Thanks in advance,

Eric

2 Answers 2

1

This is exactly the main usecase for the <xsl:namespace-alias> instruction:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:format="some:format"
 xmlns:xxx="xxx">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:namespace-alias stylesheet-prefix="xxx"
                      result-prefix="xsl"/>

 <xsl:template match="/">
    <xxx:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:format="some:format"
     >

      <xxx:template match="node()|@*">
        <xxx:copy>
          <xxx:apply-templates select="node()|@*"/>
         </xxx:copy>
      </xxx:template>
    </xxx:stylesheet>

 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the wanted result (a new stylesheet with all wanted attributes and namespaces) is produced:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:format="some:format">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Do note: Avoid using xsl:element and prefer xsl:namespace-alias whenever the transformation should generate another XSLT stylesheet.

Sign up to request clarification or add additional context in comments.

Comments

0

Try this instead:

<xsl:element name="xsl:stylesheet">
  <xsl:attribute name="version">1.0</xsl:attribute>
  <xsl:namespace name="format" select="'urn:qbo3-formatting'"/>
</xsl:element>

Alternately, instead of explicitly outputting an XML namespace, allow XSLT to autogenerate the XML namespaces once nodes of that namespace get used. If no elements are using urn:qbo3-formatting, then the namespace declaration isn't necessary.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.