Namespace nodes in XSLT and XPath

I'm trying to work out when and where namespace nodes are supposed
to be added to an XSLT result tree. Unfortunately, I'm finding that
it's not clear exactly what is supposed to go on when using various
combinations of xsl:element, xsl:attribute, and result tree fragments.

Where XSLT 7.1.1 "Literal Result Elements" is explicit about what
namespace nodes are included in a Result Tree when a literal elements
is instantiated; 7.1.2 "Creating Elements with xsl:element" and 7.1.3
"Creating Attributes with xsl:attribute" are not. (Possibly, their silence
is deliberate, and prescriptive.)

---------------------------------------------------------------------------
A simple example.

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
   <out>
     <xsl:element name="foo" namespace="http://www.foo.com/"/>
   </out>
 </xsl:template>

According to XSLT 7.1.2, 'http://www.foo.com/' (the string that resulted
from instantiating the value of the namespace attribute as an AVT) is to be
    "used as the namespace URI of the expanded-name of the element
    to be created."
Should this be interpreted as:
    'http://www.foo.com/' is to be used as the "string value" (per XPath
    5.4) of a namespace node that is to be added to the element to be
    created.
?
If so, then running the above against a simple source document,
such as "<doc/>", should generate:

  <out><foo xmlns="http://www.foo.com/"/></out>

[Alternatively, XSLT 7.1.2 doesn't *say* to create a namespace node in the
result tree from the 'namespace' attribute, just that it should be used as
the namespace URI of the created element...  in which case it generate:
  <out><foo/></out>
... but doesn't seem reasonable.]

But what about:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
   <out xmlns="http://www.foo.com/">
     <xsl:element name="foo" namespace="http://www.foo.com/"/>
   </out>
 </xsl:template>

Should this generate:
  <out xmlns="http://www.foo.com/"><foo/></out>
or:
  <out xmlns="http://www.foo.com/"><foo xmlns="http://www.foo.com/"/></out>

Clearly, from XSLT 7.1.1, the <out> element must have a copy of
the xmlns="http://www.foo.com/" namespace node. However, the
first example would suggest that so, too, should the <foo> element...

[[Note that they are *not* equivalent, as far as XPath is concerned.
Consider count()-ing the namespace axis; alternatively, consider 
the result tree that should be generated by:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
   <out xmlns="http://www.foo.com/" xmlns:bar="http://www.bar.com">
     <xsl:element name="foo" namespace="http://www.foo.com/"/>
   </out>
 </xsl:template>
What would '//foo/namespace::*[2]' identify?
The namespace 'http://www.foo.com/' or the namespace 'http://www.bar.com'?]]

---------------------------------------------------------------------------
Lastly, what happens when pasting result tree fragments into a result tree?
 From where are the namespace nodes taken when pasting a variable into a
tree? From the original context? from the context from which the variable
is pasted? For example, consider:

 <?xml version="1.0"?> 
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
 <xsl:variable name="var1" xmlns="http://www.qux.com">
     <xsl:element name="bar"/>
 </xsl:variable>
 
 <xsl:variable name="var2" xmlns:qux="http://www.qux.com">
     <xsl:element name="qux:bar"/>
 </xsl:variable>
 
 <xsl:variable name="var3" xmlns:guts="http://www.qux.com">
     <xsl:element name="guts:bar"/>
 </xsl:variable>
  
 <xsl:template match="/">
   <out>.
     <out1 xmlns="http://www.foo.com" xmlns:qux="http://www.qux.com">
      Var 1: <xsl:copy-of select="$var1"/>
      Var 2: <xsl:copy-of select="$var2"/>
      Var 3: <xsl:copy-of select="$var3"/>
       </out1>.
    </out>
 </xsl:template>
 </xsl:stylesheet>


XT produces:
<?xml version="1.0" encoding="utf-8"?>
<out>.
     <out1 xmlns:qux="http://www.qux.com" xmlns="http://www.foo.com">
          Var 1: <bar xmlns="http://www.qux.com"/>
          Var 2: <qux:bar xmlns=""/>
          Var 3: <guts:bar xmlns:guts="http://www.qux.com" xmlns=""/></out1>.
    </out>

which seems to involve examining the dynamic context in which the variable
is pasted in order to determine which namespace nodes to insert into
the result tree...

Michael
____________________________________________
http://www.mds.rmit.edu.au/~msf/
Multimedia Databases Group, RMIT, Australia.

Received on Wednesday, 28 June 2000 05:02:04 UTC