Matching elements that contain different namespaces

Discussion in 'XML' started by Hugh Sparks, Jul 30, 2004.

  1. Hugh Sparks

    Hugh Sparks Guest

    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,
     
    Hugh Sparks, Jul 30, 2004
    #1
    1. Advertising

  2. <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
     
    David Carlisle, Jul 30, 2004
    #2
    1. Advertising

  3. Hugh Sparks

    Hugh Sparks Guest

    "David Carlisle" <> wrote in message
    news:...

    > [...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,
     
    Hugh Sparks, Jul 30, 2004
    #3
  4. In article <jMrOc.1666$>,
    Hugh Sparks <> 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
     
    Richard Tobin, Jul 30, 2004
    #4
  5. Hugh Sparks

    Hugh Sparks Guest

    "Richard Tobin" <> wrote in message
    news:cedkgd$1lmu$...

    > 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,
     
    Hugh Sparks, Jul 30, 2004
    #5
  6. Hugh Sparks wrote:

    > "Richard Tobin" <> wrote in message
    > news:cedkgd$1lmu$...
    >
    >
    >>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/
     
    Martin Honnen, Jul 30, 2004
    #6
  7. In article <ABtOc.1674$>,
    Hugh Sparks <> 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
     
    Richard Tobin, Jul 30, 2004
    #7
  8. In article <ABtOc.1674$>,
    Hugh Sparks <> 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
     
    Richard Tobin, Jul 30, 2004
    #8
  9. Hugh Sparks

    Hugh Sparks Guest

    > Hugh Sparks <> wrote:

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



    "Richard Tobin" <> wrote in message
    news:cedsbg$1nqb$...
    > In article <ABtOc.1674$>,
    > 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,
     
    Hugh Sparks, Jul 30, 2004
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    692
  2. Roger Pack
    Replies:
    3
    Views:
    185
    Roger Pack
    Sep 28, 2010
  3. Frank Skare
    Replies:
    2
    Views:
    223
    Jim Cochrane
    Apr 17, 2004
  4. alan
    Replies:
    7
    Views:
    347
    Michael Slass
    Sep 2, 2004
  5. Jason Carlton
    Replies:
    11
    Views:
    268
    Dr J R Stockton
    Dec 8, 2009
Loading...

Share This Page