views:

213

answers:

1

I've got an XML document with many different namespaces in use and a schema to validate against. The schema requires that all elements be "qualified", and I assume this means that they need to have full QNames without a null namespace.

However, some elements in this giant XML document have slipped through using just the default namespace, which in the case of this document is blank. Natually, they fail validation with the schema.

I'm trying to write an XSLT that will select nodes that have no namespace and assign them a specific one with the same prefix as the others. For example:

<x:doc xmlns:x="http://thisns.com/"&gt;
  <x:node @x:property="true">
     this part passes validation
  </x:node>
  <node property="false">
     this part does not pass validation
  </node>
</x:doc>

I've tried adding xmlns="http://thisns.com/" to the root node of the document, but this does not agree with the schema validator. Any thoughts on how I can make this work?

Thanks!

+1  A: 
<!-- Identity transform by default -->
<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*"/>
  </xsl:copy>
</xsl:template>
<!-- Override identity transform for elements with blank namespace -->
<xsl:template match="*[namespace-uri() = '']">    
  <xsl:element name="{local-name()}" namespace="http://thisns.com/"&gt;
    <xsl:apply-templates select="node() | @*"/>
  </xsl:element>
</xsl:template>
<!-- Override identity transform for attributes with blank namespace -->
<xsl:template match="@*[namespace-uri() = '']">
  <xsl:attribute name="{local-name()}" namespace="http://thisns.com/"&gt;&lt;xsl:value-of  select="."/></xsl:attribute>
</xsl:template>

This will give a result similar to:

<x:doc xmlns:x="http://thisns.com/"&gt;
  <x:node x:property="true">
    this part passes validation
  </x:node>
  <node xp_0:property="false" xmlns="http://thisns.com/" xmlns:xp_0="http://thisns.com/"&gt;
     this part does not pass validation
  </node>
</x:doc>

Note that the second <node> is still without a namespace prefix, but it is now considered part of the same namespace because of the xmlns= attribute.

ckarras