[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
[xsl] Using key() from outside the default namespace
Subject: [xsl] Using key() from outside the default namespace From: Peter Flynn <peter@xxxxxxxxxxx> Date: 04 Aug 2003 18:46:49 +0100 |
I'm experimenting with portable ways of specifying bibliographic reference formatting in XML so that it can be applied to documents in any DTD or Schema. The objective is to avoid having to hard-code complex XSL[T] for every output variant, when it's far faster and easier to specify and maintain the layout using a generic document type designed for the purpose. I'm having trouble using key() to get information from the main document namespace while processing within the namespace of an auxiliary document. How do I get a key() which indexes nodes in the main namespace to work if I need to invoke it from within a for-each which places the context in a different namespace, without triggering a new instance of the output document? (See caveat at end: this is *different* from the examples in the FAQ and elsewhere that I have found. Unless I've missed something.) I have file of bibliographic references mydoc.xml (which could be DocBook's <bibliography>, TEI's <listBibl>, etc). Each entry has an ID attribute and a reference type attribute (eg Book, Article, Report, etc), and the publisher is identified in an attribute on the containing list. All standard stuff, no surprises. I have an auxiliary XML file formats.xml containing specifications of the formatting for these reference types, grouped in containers by publisher (eg Elsevier Article, Kluwer Book, IEEE Report, etc), stripped of all the typographic stuff here for simplicity: <publisher name="kluwer"> <document type="article"> <author> <surname/> <initials/> </author> <date/> <title/> <journal/> <volume/> <issue/> <pages/> </document> ... </publisher> ... When doing the references in the main file, the template which handles each entry must process the correct formatting subelements for the specified publisher and document type in their document order. This is done with a for-each on document('formats.xml')//publisher[@name=$publisher]/document[@type=$entrytype]/* So far, so good: this ensures the output occurs in the correct sequence. I have keys set up which identify the relevant element from the main file for each of the formatting subelements processed, eg <xsl:key name="kluwer-article-author-surname" match="//biblioentry/author/surname" use="ancestor::biblioentry/@id"/> But it is necessary to use these keys while inside the for-each which handles the formatting subelements (it also calls a named template which handles the output formatting), so the context node is inside the namespace of the formats.xml file, not the main file. They keys have been tested with a value-of while in the default (main file) namespace, and they correctly return the desired values. I did make one attempt by using a namespace on the main file, so the key names (and thus the first argument to the key function) were of the form docbook:kluwer-article-author-surname, but this didn't return any values. The recommendation in most books and the FAQ is to use a dummy for-each on a global variable to change the namespace back to the main document, eg <xsl:variable name="maindoc" select="/"/> <xsl:for-each select="biblioentry"> ...set up variables to hold this entry ID and construct the publisher-documenttype-elements key names... <xsl:for-each select="document(as above...)"> <xsl:call-template name="formatter"> ...various parameters... <xsl:with-param name="data-source"> <xsl:for-each select="$maindoc"> <xsl:value-of select="key($pub-doc-path,$entryID)"/> </xsl:for-each> </xsl:with-param> </xsl:call-template> </xsl:for-each> ... The value-of for the key() works *outside* the for-each on document() (of course, being in the default namespace), but this method outputs a new <html><head><title>...</title><link to css></head><body>foo</body></html> for *every* formatting subelement processed. Probably unsurprisingly, as it's returning to the main namespace with a node-set, so it looks for a matching template and fires it. It does of course also output the data retrieved from the key...but how do I prevent it firing an unwanted template at the same time. I've experimented with making $maindoc point at other (innocuous) locations in the main document, but that still triggers what Saxon sees as a new instance of the output document. ** $64,000 question (actually I'll buy a pint in Philly) ** * * * How do I get a key() which indexes nodes in the main * * namespace to work if I need to invoke it from within * * a for-each which places the context in a different * * namespace, without triggering a new instance of the * * output document? * * * *********************************************************** Note this is *different* from the examples I have seen, which merely want to reference a key() in another namespace *from within the default namespace*. That one's easy. This one doesn't seem to be. ///Peter XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XSL-friendly web hosting , Mike Haarman | Thread | [xsl] How to filter records with th, Joseph Tan |
RE: [xsl] Header/Footer asking., Michael Kay | Date | RE: [xsl] Need to wrap XML in <![CD, Michael Kay |
Month |
Keywords