xsl-list
[Top] [All Lists]

Re: namespace aware template matching

2005-10-27 01:32:28
tom(_dot_)kirkpatrick(_at_)virusbtn(_dot_)com wrote on 27/10/2005 09:03:18:

I'm trying to do some rather complicated, namespace aware XPath (XSLT1) 
template matching:

Given a structure like this, where <dynamic> could actually be any 
number 
(including 0) of elements in a namespace other than 
'uri://ns-namespace':

<ns:root xmlns:ns="uri://ns-namespace">
    <ns:id> id from ns:root/ns:id </ns:id>
    <dynamic>
        <ns:article>
            <dynamic>
                <ns:id> id from ns:root/ns:article/ns:id </ns:id>
            </dynamic>
        </ns:article>
        <ns:issue>
            <dynamic>
                <more tags>
                   <ns:id> id from ns:root/ns:issue/ns:id </ns:id>
                </more tags>
            </dynamic>
        </ns:issue>
    </dynamic>
</ns:root>


I need a template which matches all <ns:id> elements whoose path from 
the 
<ns:root> node is simply 'ns:root/ns:article/ns:id'. So I need to be 
able 
o exclude all elements from any namespace which is not 'ns'.

What I mean is something like this: (although it doesn't work!)

<xsl:template match="ns:root/*[namespace-uri() != 
'uri://ns-namespace']/ns:article/*[namespace-uri() != 
'uri://ns-namespace']/ns:id"/>
</xsl:template>

But this doesn't match the case where there are no foreign elements 
(whose 
namespace is not 'ns') or more than one foreign element in between 
ns:root 
and ns:article or between ns:article and ns:id.


The clocest I came was:
<xsl:template match="ns:id[ancestor::ns:article/ancestor::ns:root]"/>

But this one doesn't stipulate that the ancestor::ns:article who has an 
ancestor::ns:root must be the first 'ns' ancestor we meet, so It will 
also 
match:

<ns:root xmlns:ns="uri://ns-namespace">
    <ns:id> id from ns:root/ns:id </ns:id>
    <dynamic>
        <ns:test>
            <ns:article>
                <ns:test2>
                    <dynamic>
                        <ns:id> id from 
ns:root/ns:test/ns:article/ns:test2/ns:id </ns:id>

How can I specify that the ancestor::ns:article element must be the 
first 
one we come accross when working up the acnestor chain?

originally I had tried saying ancestor::ns:article[1], which did not seem 
to work as it would test to see if the first ancestor element was a 
ns:article, which is not what I want. I want to find the first ns:article 
element up the ancestor chain...

What I have just tried now, which seems to work (fingers crossed) is 
ancestor::ns:article[position()=1], which look very similar, yet seems to 
act differently - in the way that I want it to.

So I end up with 
ns:id/ancestor::ns:article[position()=1]/ancestor::ns:root[position()=1]

Can anyone see any problems with this method? Are there any optimizations 
I could make?


any thoughts?


thanks

-- 
Tom Kirkpatrick
Web Developer - Virus Bulletin

--~------------------------------------------------------------------
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>
--~--



-- 
Tom Kirkpatrick
Web Developer - Virus Bulletin

--~------------------------------------------------------------------
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>
--~--



<Prev in Thread] Current Thread [Next in Thread>