removing spurious namespace declarations on XSLT output

A

Andy Fish

hi,

I have an XSLT which is producing XML output.

many of the nodes in the output tree contain namespace declarations for
namespaces that are used in the source document even though they are not
used in the result document or the stylesheet

also I find that (for namespaces that are referenced in the stylesheet) even
if I put an explicit namespace declaration on the root element of the result
tree, namespaces declarations are repeated on individual nodes of the result
tree but with a different prefix

all I want is that for namespaces used in the result tree, they are declared
on the root element, and other namespaces shouldn't be output at all. why is
this so difficult to achieve or am I missing something big here?

TIA

Andy
 
A

Andy Fish

typical - after tearing my hair out on it for hours, I made some progress
just after posting the question

it appears the spurious namespace declarations are due to me using
<xsl:copy> which copies all namespace declarations from the source node,
regardless of whether they are used

so my new question is, how can I replicate the behaviour of <xsl:copy>
without copying all the namespace declarations?

Andy
 
R

Richard Tobin

Andy Fish said:
it appears the spurious namespace declarations are due to me using
<xsl:copy> which copies all namespace declarations from the source node,
regardless of whether they are used

so my new question is, how can I replicate the behaviour of <xsl:copy>
without copying all the namespace declarations?

You could copy elements by creating new elements:

<xsl:element name="local-name()" namespace="namespace-uri()">
<xsl:copy-of select="@*"/>
...
</xsl:element>

-- Richard
 
M

Martin Honnen

Andy said:
I have an XSLT which is producing XML output.

many of the nodes in the output tree contain namespace declarations for
namespaces that are used in the source document even though they are not
used in the result document or the stylesheet

Are you using exclude-result-prefixes on the xsl:stylesheet element
<http://www.w3.org/TR/xslt#stylesheet-element>
That way you should get rid of namespace declarations for namespaces
that are not used in the result document.
 
R

Richard Tobin

many of the nodes in the output tree contain namespace declarations for
namespaces that are used in the source document even though they are not
used in the result document or the stylesheet
[/QUOTE]
Are you using exclude-result-prefixes on the xsl:stylesheet element
<http://www.w3.org/TR/xslt#stylesheet-element>
That way you should get rid of namespace declarations for namespaces
that are not used in the result document.

That only suppresses namespaces appearing in the stylesheet, not ones
copied from the source document.

-- Richard
 
A

Andy Fish

thanks richard

I have used something similar to this technique. unfortunately yours creates
a namespace node on the copied node of the result tree and I wanted to just
use the prefix.

I tried this

<xsl:element name="{name()}" >

but it fails if the namespace prefix in the source document is different to
that used in the stylesheet, so I ended up with this instead

<xsl:template match="foo:*">
<xsl:element name="foo:{local-name()}" >
<xsl:for-each select="@*">
<xsl:attribute name="foo:{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:for-each>
</xsl:element>
</xsl:template>
 
J

Joe Kesselman

Andy said:
I have used something similar to this technique. unfortunately yours creates
a namespace node on the copied node of the result tree and I wanted to just
use the prefix.

XSLT is namespace-aware. When you copy a node, you copy it with its
namespace context, because that's part of the meaning of the node.

If you really want to break namespace-aware behavior, then yes,
hand-constructing a new node is one solution. But I strongly suspect
that what you're really looking for is
http://www.w3.org/TR/1999/REC-xslt-19991116#element-namespace-alias
 
J

Joe Kesselman

Andy said:
it appears the spurious namespace declarations are due to me using
<xsl:copy> which copies all namespace declarations from the source node,
regardless of whether they are used

BTW, the reason it does this is because there's no good way for XSLT to
be sure whether those declarations are or aren't used. Consider, for
example, a document which contains an XPath; that path is often
dependant upon prefixes in scope around it, but there's no guaranteed
way for XSLT to determine that those dependencies exist. Much, much,
MUCH safer to copy all the declarations (which should be harmless at
worst if they aren't used).

The only argument for not copying them is that DTDs have trouble with
unexpected namespace declarations. But DTDs really don't play nicely
with namespaces anyway, which is why I keep telling folks to switch to
schemas.
 
A

Andy Fish

the issue is that I don't know what namespace prefix might have been used in
the source document. in the output document I want to use the same namespace
I'm using in the stylesheet

I did investigate <xsl:namespace-alias> but I can't see how this would help.
 
J

Joe Kesselman

Andy said:
the issue is that I don't know what namespace prefix might have been used in
the source document. in the output document I want to use the same namespace
I'm using in the stylesheet

If you copy a node from the stylesheet to the output, it will have the
same namespace, and namespace bindings, as in the stylesheet.

If you copy a node from a source document to the output, it will have
the same namespace, and namespace bindings, as in the source document.

Appropriate declarations will be generated to make it so, if the
relevant binding from prefix to namespace URI isn't already in scope at
that point in the output. They aren't "spurious"; they're required to
achieve the above semantic results.


If you're having trouble, it's because you either aren't trusting
xsl:copy to do the right thing, or because you're trying to override
those semantics, or because you're not using namespaces properly... or
because you're worried about validating against a DTD which doesn't
allow the relevant namespace declarations at that point in the document.
If it's the last, the best advice I can give you is to abandon DTDs; the
namespace spec deliberately chose not to worry about "playing nice" with
DTDs, and its authors advised everyone to switch to XML Schema -- which,
unlike DTDs, is fully namespace-aware.



It might help if you gave us a more explicit example of what you're
trying to do. You've given us a request out of context, and a fragment
of code that attempts to meet that request... but both presuppose a
particular solution, and it may not be the right solution. Consider
posting a minimal example that demonstrates what you think is a problem,
and explaining exactly why you consider it a problem. You'll get better
answers if you ask the real question rather than asking about a detail.
 
J

Joseph Kesselman

Andy said:
the issue is that I don't know what namespace prefix might have been used in
the source document.

Don't think in terms of prefixes. A prefix is just shorthand for a
namespace URI, and nothing namespace-aware should care which prefix is
used, only which namespace.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top