Subject: Re: How to remove unnecessary "xmlns:xx" attributes?
From: Wolfgang Laun <wolfgang.laun@xxxxxxxxx>
Date: Wed, 10 Nov 2010 11:11:13 +0100
|
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@xxxxxxxxxxxxxxxx> 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?
>
>
> ======================================================================
> Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx
> 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
> ======================================================================
|