467,861 Members | 1,432 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,861 developers. It's quick & easy.

Matching elements that contain different namespaces

When processing an xml document that contains elements such as:

<element xmlns="goop"/>
...
<element xmlns="gleep"/>

I want to create two xsl stylesheet templates: one that matches
the elements that contain the namespace declaration for "goop"
and one that matches the elements that contain the namespace
declaration for "gleep".

How should the match patterns be written?

Thanks!

-Hugh Sparks, hu**@csparks.com
Jul 20 '05 #1
  • viewed: 1754
Share:
8 Replies

<xsl:template match="a:element">
....

<xsl:template match="b:element">
....
together with

xmlns:a="goop"
xmlns:b="gleep"

either on those selments, or more typically on the xsl:stylesheet
element, so it is in scope for the whole stylesheet.

Note you have to do this even if you only had one namespace, unprefixed
names in XPathe xpressions and XSLT patterns always refer to no-namespace.

David
Jul 20 '05 #2
"David Carlisle" <da****@nag.co.uk> wrote in message
news:yg*************@penguin.nag.co.uk...
[...How to match elements from different namespaces...] <xsl:template match="a:element">
...
<xsl:template match="b:element">
...
together with

xmlns:a="goop"
xmlns:b="gleep"
Thank you: That is a very clear answer.
I simplified too much. My problem is a little more bizarre.

I'm not even sure if this is legal xml, but this is what I'm trying to deal
with:

My document contains elements like this:

<document xmlns="MyStuff">
....
<fe:fragment xmlns="goop" xmlns:fe="Fragment" fragment-id="123"/>
....
<fe:fragment xmlns="gleep" xmlns:fe="Fragment" fragment-id="456"/>
....
</document>

The stylesheet root element looks like this:

<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fe="Fragment"


I want to write one template that matches the fe:fragment that contains
xmlns="goop" and one template that matches the fe:fragment the contains
the xmlns="gleep".

The fe:fragments are created by a piece of software I don't entirely
control.
It seems to me that the fe:fragment elements have conflicting namepace
membership. Is this legal XML by itself:

<fe:fragment xmlns:fe="Fragment"/>

In other words, can you use a namespace prefix on an element that
contains the prefix definition? I though it could only be used by the
element's children...

I found that my stylesheet didn't work if I didn't define the fe prefix
in the stylesheet root.

And what does this mean:

<root xmlns:fe="Fragment">
<fe:fragment xmlns="goop" xmlns:fe="Fragment"/>
</root>

What is the namespace of fe:fragment?
Is the internal xmlns:fe="Fragment" necessary? Sufficient?
Is this legal xml at all?

In case you're interested in the larger context, the fe:fragments are
created by
by Apache Cocoon's FragmentExtractorTransformer. I have a source document
that I need to extract two different elements for processing by two
different external
Cocoon serializers. When a fragment extractors is configured, you specify
the element name you want to extract and the element's namespace URI.

The intermediate xml document is sent to the stylesheet with the elements
extracted and replaced by the <fe:fragment> elements shown above.
The stylesheet rearranges things a bit and the fragments go back to
the Cocoon pipeline where the original elements get looked up and their
content gets processed.

The only way to distinguish the fragments is by their id attribute and
by the xmlns="blah" they contain. The xmlns="blah" is the namespace
of the extracted element. The fragment does not explicity contain the
name of the element it replaced, which seems like a Bad Thing to me.

I need to handle the fragments differently in the stylesheet depending
on the element they came from. In my case, it happens that each
of the two elements is in a different namespace. So if I can
write the proper template, I can handle the fragments properly.

Thanks,

Hugh Sparks, hu**@csparks.com
Jul 20 '05 #3
In article <jM****************@news01.roc.ny>,
Hugh Sparks <hu**@csparks.com> wrote:
I want to write one template that matches the fe:fragment that contains
xmlns="goop" and one template that matches the fe:fragment the contains
the xmlns="gleep".
Why?
Is this legal XML by itself:

<fe:fragment xmlns:fe="Fragment"/>
Yes.
In other words, can you use a namespace prefix on an element that
contains the prefix definition?
Yes.
I found that my stylesheet didn't work if I didn't define the fe prefix
in the stylesheet root.
It should be sufficient to declare it on the elements that use it.
And what does this mean:

<root xmlns:fe="Fragment">
<fe:fragment xmlns="goop" xmlns:fe="Fragment"/>
</root>

What is the namespace of fe:fragment?


"Fragment".

The xmlns="goop" is useless in this example.

-- Richard
Jul 20 '05 #4

"Richard Tobin" <ri*****@cogsci.ed.ac.uk> wrote in message
news:ce***********@pc-news.cogsci.ed.ac.uk...
The xmlns="goop" is useless in this example.


Yes, I suspected that.

Just out of curiosity, is the extra xmlns entirely useless?
Wouldn't it apply to the child elements of the fe:fragment?

(I didn't create the fe:fragment elements.
A confounded piece of Cocoon software did that.)

I just want to distinguish the fragments with xslt templates
based on the useless default namespace declarations they
contain. Any ideas?

Thanks,

Hugh Sparks, hu**@csparks.com
Jul 20 '05 #5


Hugh Sparks wrote:
"Richard Tobin" <ri*****@cogsci.ed.ac.uk> wrote in message
news:ce***********@pc-news.cogsci.ed.ac.uk...

The xmlns="goop" is useless in this example.

Yes, I suspected that.

Just out of curiosity, is the extra xmlns entirely useless?
Wouldn't it apply to the child elements of the fe:fragment?


It sets a default namespace for the child elements so if there are any
child elements without a prefix in their name then that xmlns="goop"
would indeed apply to them. But you posted
<fe:fragment xmlns="goop" xmlns:fe="Fragment" fragment-id="123"/>
which is an empty element so in that case there are no child elements
and the xmlns="goop" is useless.

--

Martin Honnen
http://JavaScript.FAQTs.com/

Jul 20 '05 #6
In article <AB*****************@news01.roc.ny>,
Hugh Sparks <hu**@csparks.com> wrote:
Just out of curiosity, is the extra xmlns entirely useless?
Wouldn't it apply to the child elements of the fe:fragment?


Yes, the reason I said it was useless was that there were no children
in the example.

-- Richard
Jul 20 '05 #7
In article <AB*****************@news01.roc.ny>,
Hugh Sparks <hu**@csparks.com> wrote:
I just want to distinguish the fragments with xslt templates
based on the useless default namespace declarations they
contain. Any ideas?


The xmlns declarations themselves don't appear in the XPath data model,
so you can't test for them directly.

But the resulting in-scope-namespaces *do* appear in the data model.

This will match any element that has a prefix or the default namespace
bound to "goop":

*[namespace::* = 'goop']

If you insist on it being the default namespace it's a bit trickier:

*[namespace::*[name()=''] = 'goop']

Those will also match descendants of the elements with the
xmlns="goop" declaration, unless they have xmlns= declarations of
their own. If you only want to match the top-level ones, use

*[namespace::* = 'goop'][not(../namespace::* = 'goop')]

-- Richard
Jul 20 '05 #8
> Hugh Sparks <hu**@csparks.com> wrote:
I just want to distinguish the fragments with xslt templates
based on the useless default namespace declarations they
contain. Any ideas?


"Richard Tobin" <ri*****@cogsci.ed.ac.uk> wrote in message
news:ce***********@pc-news.cogsci.ed.ac.uk... In article <AB*****************@news01.roc.ny>,
This will match any element that has a prefix or the default namespace
bound to "goop":

*[namespace::* = 'goop']

[...More profound stuff...]


So to distinguish only my cocoon fragments, the templates would be:

<xsl:template match="fe:fragment[namespace::*='goop']">
...
</xsl:template>
<xsl:template match="fe:fragment[namespace::*='gleep']">
...
</xsl:template>

It works!!

I'm going to ask the author of the FragmentExtractorTransformer about
adding a fragment-name attribute with a value that contains the replaced
element name. That would avoid this obscure difficulty. It's not always
possible for the extracted elements to come from different namespaces.

Thanks very much,

Hugh Sparks, hu**@csparks.com
Jul 20 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Shannon Hughes | last post: by
1 post views Thread by Lothar Lemnitzer | last post: by
11 posts views Thread by solandre | last post: by
11 posts views Thread by tech | last post: by
reply views Thread by jack112 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.