This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Finding namespace definitions (Was: Re: check if nodes match xpath expression)


Dimitre,

> 2. The stylesheet that does 100% of the processing (although heavily
> based on the original MS defaultss.xsl) is pure XSLT and could easily
> be used with another XSLT processor. The only extension function that
> is used is to get the "xml" property of a node. Something like this
> will be necessary regardless of which XSLT processor is being used. The
> reason is that it is not possible without extensions to determine the
> fact (of) and exact location of a namespace definition. 

As long as you're happy with pinpointing the element that holds it
(rather than e.g. where it occurs within the start tag), then can't
you do that with judicious use of the namespace:: axis?

The namespace definitions that are in scope for a particular element
can be accessed with:

  namespace::*

The element a namespace is defined on is the top-most ancestor element
that has a namespace:: with the same name() and string value, i.e.:

  ancestor-or-self::*[namespace::*[name() = $namespace-prefix and
                                   . = $namespace-uri]][last()]

So, for example, you can print what namespaces an element defines with
the template:
                                   
<xsl:template match="*" mode="namespace">
   <xsl:for-each select="namespace::*">
      <xsl:if test="not(../ancestor::*[namespace::*[name() = name(current()) and
                                       . = current()]][last()])">
         <xsl:value-of select="name(..)" /> defines <xsl:text />
         <xsl:choose>
            <xsl:when test="name()">xmlns:<xsl:value-of select="name()" /></xsl:when>
            <xsl:otherwise>xmlns</xsl:otherwise>
         </xsl:choose>
         <xsl:text />="<xsl:value-of select="." />"&#xA;<xsl:text />
      </xsl:if>
   </xsl:for-each>
</xsl:template>

[As reported here previously, MSXML3 returns 'xmlns:foo' rather than
simply 'foo' when accessing the name() of the namespace, but this does
not affect the operation of the above.]

Note also that the 'xml' namespace is always declared on the top
element: it needs to be filtered out if you want only those namespaces
that are declared explicitly.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]