Your solution includes a lot of repeat messages. You also don't check
for whether attributes use the namespace. Here's one that avoids both
problems:
<xsl:template match="/">
<xsl:for-each select="//namespace::*[not(. =
(preceding::*|../ancestor::*)/namespace::*)]">
<xsl:if test="not((//* | //@*)[namespace-uri(.) = current()])">
This namespace is unused: <xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
Things are much easier in XSLT/XPath 2.0 (assuming current() bound to
document node):
distinct-values(//namespace::*)[not(. =
(current()//*|current()//@*)/namespace-uri(.))]
Neither of our solutions checks for unused prefixes, e.g., if the
document had multiple declarations for the same URI but uses only one of
the prefixes on element/attribute names. That could be done in XSLT 2.0,
but whether or not it would work in XSLT 1.0 is dependent on how your
processor implements name(). (XPath 2.0 provides direct access to what
prefix was used, but XPath 1.0 does not.)
Keep in mind that the above tests don't guarantee that the namespace
isn't "used." If your input document is XSLT, XSD, or any other
vocabulary that uses QNames in content, you can't safely assume the
namespace isn't being used.
Evan
--
Evan Lenz
Lenz Consulting Group, Inc.
http://lenzconsulting.com
+1 (360) 297-0087
Costello, Roger L. wrote:
Hi Folks,
Consider this XML document:
<?xml version="1.0"?>
<N1:NumberList xmlns:N1="http://www.example1.org"
xmlns:N2="http://www.example2.org">
<Number>23</Number>
<Number>41</Number>
<Number xmlns:N3="http://www.example3.org">70</Number>
<Number>103</Number>
<Number>99</Number>
<Number>6</Number>
</N1:NumberList>
Notice that there are three (3) namespaces, but two of them are unused:
http://www.example2.org
http://www.example3.org
I want an XSLT transform that will output all the unused namespaces in the input XML document.
Here's the solution I came up with:
<xsl:template match="*">
<xsl:variable name="elem" select="." />
<xsl:for-each select="namespace::*[. !=
'http://www.w3.org/XML/1998/namespace']">
<xsl:variable name="ns" select="." />
<xsl:if test="not($elem/ancestor::*[namespace::* = $ns])">
<xsl:if test="not($elem/descendant-or-self::*[namespace-uri() = $ns])">
This namespace is unused: <xsl:value-of select="$ns" />
</xsl:if>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="*" />
</xsl:template>
Is there a better solution? (I am using XSLT 1.0)
/Roger
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--