If one of the grand wizards would kindly review my solution:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="/node()">
<xsl:copy copy-namespaces = "no">
<xsl:for-each-group select = "descendant-or-self::node()"
group-by = "node-name(.)">
<xsl:variable name="key" select="current-grouping-key()"/>
<xsl:if test="namespace-uri-from-QName($key)">
<xsl:namespace name="{ prefix-from-QName($key) }">
<xsl:value-of select="namespace-uri-from-QName($key)"/>
</xsl:namespace>
</xsl:if>
</xsl:for-each-group>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|*">
<xsl:copy copy-namespaces = "no">
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Input:
<doc xmlns:abc="a/b/c" xmlns:xyz="x/y/z" xmlns="p/q/r">
<abc:bef>The quick brown fox jumps over the lazy dog</abc:bef>
<para doc="jar">a para 1</para>
<para doc="file">a para 2</para>
<def:dir xmlns:def="d/e/f" xmlns:uvw="u/v/w">
<num>4123456</num>
<num>412345</num>
<num>41234567</num>
<ghi:num xmlns:ghi="g/h/i">1242345678</ghi:num>
<num>4222</num>
</def:dir>
</doc>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<doc xmlns="p/q/r" xmlns:abc="a/b/c" xmlns:def="d/e/f" xmlns:ghi="g/h/i">
<abc:bef>The quick brown fox jumps over the lazy dog</abc:bef>
<para doc="jar">a para 1</para>
<para doc="file">a para 2</para>
<def:dir>
<num>4123456</num>
<num>412345</num>
<num>41234567</num>
<ghi:num>1242345678</ghi:num>
<num>4222</num>
</def:dir>
</doc>
On 10 November 2010 00:07, Wendell Piez <wapiez(_at_)mulberrytech(_dot_)com>
wrote:
David,
I assume we are talking about a stylesheet that would copy all the input
except any namespaces that are not actually used, giving a result document in
which they were not declared.
This is easier to do in XSLT 2.0 than in XSLT 1.0. If you need an XSLT 1.0
solution you should say so.
In XSLT 2.0, this could be accomplished by an stylesheet with an identity
template set with copy-namespaces="no", and a template matching the document
node (top-level element) that would reach into the document, group its
elements and attributes by their namespace (the one actually used), and copy
a namespace node for each group to the document element.
The result would be a document in which each of the namespaces actually used
would be declared at the top level.
Unfortunately I don't have time at the moment to mock this up for you, but it
shouldn't be all that hard, given facilities in XSLT 2.0 (for grouping) and
XPath 2.0 (namespace-uri() and friends, for determining namespaces used in
names).
Keep in mind that additional complications could arise if you ever have
clashing namespaces (same namespace and different prefix or same prefix
different namespace). Hopefully you don't.
Cheers,
Wendell
At 01:58 PM 11/9/2010, you wrote:
I currently have an ad hoc Soap client framework that uses JAXB to
marshal a Soap request. This generates a "minimal" Soap envelope, in
that it contains a "xmlns:xx" attribute for every "xx" that is actually
referenced in the request.
The WSDL that defines this request references numerous schemas, and
defines all the possible operations for this service.
I'm now doing an experiment to see if I can replace our ad hoc Soap
client framework with Apache CXF. My results so far are ok, but I
noticed that the request that is built now contains "xmlns:xx"
attributes for EVERY schema referenced in the WSDL, even if that
namespace isn't referenced in the request. As a result, my requests are
now 20 times larger.
I'm examining whether it's possible to get back to what I had before,
although with the new framework, but I think it may not be practical.
I'm not even sure the resulting larger request will result in any
increased latency. It might make no difference, from a performance
point of view.
However, these requests are occasionally saved and passed back and forth
in email, to discuss certain operational issues. It would be ideal if
these requests are "minimal". If I can't solve this problem at runtime,
I'd at least like to have an XSLT stylesheet that can "minimize" the
request by simply removing the "xmlns:xx" attributes where the namespace
referred to by the "xx" prefix is not referenced in the request. I've
googled about this, but I haven't found a clear solution for this. Does
someone have an idea how I would write a stylesheet to do this?
--~------------------------------------------------------------------
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>
--~--
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
--~------------------------------------------------------------------
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>
--~--